polserver/pol-core/pol/module/guildmod.cpp

460 lines
13 KiB
C++
Raw Permalink Normal View History

/** @file
*
* @par History
* - 2005/11/26 Shinigami: changed "strcmp" into "stricmp" to suppress Script Errors
* - 2006/09/27 Shinigami: GCC 3.4.x fix - added "template<>" to TmplExecutorModule
* - 2007/06/17 Shinigami: added config.world_data_path
* - 2009/12/21 Turley: ._method() call fix
*/
2016-02-11 22:54:43 +01:00
#include "guildmod.h"
#include <stddef.h>
2016-02-11 22:54:43 +01:00
#include "../../bscript/berror.h"
#include "../../bscript/executor.h"
2016-02-11 22:54:43 +01:00
#include "../../bscript/objmembers.h"
#include "../../bscript/objmethods.h"
#include "../../clib/rawtypes.h"
#include "../../clib/stlutil.h"
#include "../fnsearch.h"
2016-02-11 22:54:43 +01:00
#include "../globals/uvars.h"
#include "../guilds.h"
#include "../guildscrobj.h"
2016-02-11 22:54:43 +01:00
#include "../mobile/charactr.h"
#include "../polobject.h"
#include "../uoexec.h"
#include "../uoscrobj.h"
#include <module_defs/guilds.h>
#include <memory>
namespace Pol::Module
2016-10-23 17:32:09 +02:00
{
using namespace Bscript;
using UOExecutor = Core::UOExecutor;
/// Guild Object
/// Properties:
/// guild.guildid : integer
/// guild.members : array of offline mobilerefs
/// guild.allyguilds : array of allied guilds
/// guild.enemyguilds : array of enemy guilds
///
/// Methods:
/// guild.ismember( who )
/// guild.isallyguild( guild )
/// guild.isenemyguild(guild)
///
/// guild.addmember( who )
/// guild.addallyguild( guild )
/// guild.addenemyguild( guild )
///
/// guild.removemember( who )
/// guild.removeallyguild( guild )
/// guild.removeenemyguild( guild )
///
/// guild.getprop( propname )
/// guild.setprop( propname, propvalue )
/// guild.eraseprop( propname )
///
BObjectImp* GuildExecutorModule::CreateGuildRefObjImp( Core::Guild* guild )
{
return new EGuildRefObjImp( ref_ptr<Core::Guild>( guild ) );
}
bool getGuildParam( Executor& exec, unsigned param, Core::Guild*& guild, BError*& err )
{
2018-07-31 14:30:29 +02:00
BApplicObjBase* aob = nullptr;
if ( exec.hasParams( param + 1 ) )
aob = exec.getApplicObjParam( param, &guild_type );
2018-07-31 14:30:29 +02:00
if ( aob == nullptr )
{
err = new BError( "Invalid parameter type" );
return false;
}
EGuildRefObjImp* gr = static_cast<EGuildRefObjImp*>( aob );
guild = gr->value().get();
if ( guild->disbanded() )
{
err = new BError( "Guild has disbanded" );
return false;
}
return true;
}
BObjectRef EGuildRefObjImp::get_member_id( const int id ) // id test
{
if ( obj_->_disbanded )
return BObjectRef( new BError( "Guild has disbanded" ) );
switch ( id )
{
case MBR_MEMBERS:
{
std::unique_ptr<ObjArray> arr;
arr = std::make_unique<ObjArray>();
for ( Core::SerialSet::iterator itr = obj_->_member_serials.begin();
itr != obj_->_member_serials.end();
/* do this earlier */ )
{
unsigned int mserial = ( *itr );
Core::SerialSet::iterator last_itr = itr;
++itr;
Mobile::Character* chr = Core::system_find_mobile( mserial );
2018-07-31 14:30:29 +02:00
if ( chr != nullptr )
{
arr->addElement( new EOfflineCharacterRefObjImp( chr ) );
}
else
{
obj_->_member_serials.erase( last_itr );
}
}
return BObjectRef( arr.release() );
}
case MBR_ALLYGUILDS:
{
std::unique_ptr<ObjArray> arr;
arr = std::make_unique<ObjArray>();
for ( Core::SerialSet::iterator itr = obj_->_allyguild_serials.begin();
itr != obj_->_allyguild_serials.end();
/* do this earlier */ )
{
unsigned int gserial = ( *itr );
Core::SerialSet::iterator last_itr = itr;
++itr;
Core::Guild* guild = Core::Guild::FindGuild( gserial );
2018-07-31 14:30:29 +02:00
if ( guild != nullptr )
{
arr->addElement( new EGuildRefObjImp( ref_ptr<Core::Guild>( guild ) ) );
}
else
{
obj_->_allyguild_serials.erase( last_itr );
}
}
return BObjectRef( arr.release() );
}
case MBR_ENEMYGUILDS:
{
std::unique_ptr<ObjArray> arr;
arr = std::make_unique<ObjArray>();
for ( Core::SerialSet::iterator itr = obj_->_enemyguild_serials.begin();
itr != obj_->_enemyguild_serials.end();
/* do this earlier */ )
{
unsigned int gserial = ( *itr );
Core::SerialSet::iterator last_itr = itr;
++itr;
Core::Guild* guild = Core::Guild::FindGuild( gserial );
2018-07-31 14:30:29 +02:00
if ( guild != nullptr )
{
arr->addElement( new EGuildRefObjImp( ref_ptr<Core::Guild>( guild ) ) );
}
else
{
obj_->_enemyguild_serials.erase( last_itr );
}
}
return BObjectRef( arr.release() );
}
case MBR_GUILDID:
return BObjectRef( new BLong( obj_->_guildid ) );
default:
return BObjectRef( UninitObject::create() );
}
}
BObjectRef EGuildRefObjImp::get_member( const char* membername )
{
if ( obj_->_disbanded )
return BObjectRef( new BError( "Guild has disbanded" ) );
ObjMember* objmember = getKnownObjMember( membername );
2018-07-31 14:30:29 +02:00
if ( objmember != nullptr )
return this->get_member_id( objmember->id );
return BObjectRef( UninitObject::create() );
}
BObjectImp* EGuildRefObjImp::call_polmethod_id( const int id, UOExecutor& ex, bool forcebuiltin )
{
if ( obj_->_disbanded )
return new BError( "Guild has disbanded" );
ObjMethod* mth = getObjMethod( id );
if ( mth->overridden && !forcebuiltin )
{
auto* result = Core::gamestate.system_hooks.call_script_method( mth->code, &ex, this );
if ( result )
return result;
}
switch ( id )
{
case MTH_ISMEMBER:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Mobile::Character* chr;
if ( !ex.getCharacterParam( 0, chr ) )
return new BError( "Invalid parameter type" );
return new BLong( static_cast<int>( obj_->_member_serials.count( chr->serial ) ) );
}
case MTH_ISALLYGUILD:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Core::Guild* allyguild;
BError* err;
if ( getGuildParam( ex, 0, allyguild, err ) )
return new BLong(
static_cast<int>( obj_->_allyguild_serials.count( allyguild->guildid() ) ) );
return err;
}
case MTH_ISENEMYGUILD:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Core::Guild* enemyguild;
BError* err;
if ( getGuildParam( ex, 0, enemyguild, err ) )
return new BLong(
static_cast<int>( obj_->_enemyguild_serials.count( enemyguild->guildid() ) ) );
return err;
}
case MTH_ADDMEMBER:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Mobile::Character* chr;
if ( !ex.getCharacterParam( 0, chr ) )
return new BError( "Invalid parameter type" );
if ( chr->guildid() )
return new BError( "Character already belongs to a guild" );
chr->guild( obj_.get() );
obj_->_member_serials.insert( chr->serial );
// MuadDib Added to update online members when status changes.
obj_->update_online_members();
return new BLong( 1 );
}
case MTH_ADDALLYGUILD:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Core::Guild* allyguild;
BError* err;
if ( getGuildParam( ex, 0, allyguild, err ) )
{
if ( obj_->_enemyguild_serials.count( allyguild->guildid() ) )
return new BError( "That is an enemy guild" );
if ( allyguild->guildid() == obj_->guildid() )
return new BError( "Passed self as new ally guild" );
obj_->_allyguild_serials.insert( allyguild->guildid() );
allyguild->_allyguild_serials.insert( obj_->_guildid );
// MuadDib Added to update online members when status changes.
obj_->update_online_members();
allyguild->update_online_members();
return new BLong( 1 );
}
return err;
2016-02-11 22:54:43 +01:00
}
case MTH_ADDENEMYGUILD:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Core::Guild* enemyguild;
BError* err;
if ( getGuildParam( ex, 0, enemyguild, err ) )
{
if ( obj_->_allyguild_serials.count( enemyguild->guildid() ) )
return new BError( "That is an ally guild" );
if ( enemyguild->guildid() == obj_->guildid() )
return new BError( "Passed self as new enemy guild" );
obj_->_enemyguild_serials.insert( enemyguild->guildid() );
enemyguild->_enemyguild_serials.insert( obj_->_guildid );
// MuadDib Added to update online members when status changes.
obj_->update_online_members();
enemyguild->update_online_members();
return new BLong( 1 );
}
return err;
}
case MTH_REMOVEMEMBER:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Mobile::Character* chr;
if ( !ex.getCharacterParam( 0, chr ) )
return new BError( "Invalid parameter type" );
if ( chr->guildid() != obj_->_guildid )
return new BError( "Character does not belong to this guild" );
2018-07-31 14:30:29 +02:00
chr->guild( nullptr );
obj_->_member_serials.erase( chr->serial );
// MuadDib Added to update online members when status changes.
obj_->update_online_members_remove( chr );
return new BLong( 1 );
}
case MTH_REMOVEALLYGUILD:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Core::Guild* allyguild;
BError* err;
if ( getGuildParam( ex, 0, allyguild, err ) )
{
if ( !obj_->_allyguild_serials.count( allyguild->guildid() ) )
return new BError( "That is not an ally guild" );
obj_->_allyguild_serials.erase( allyguild->guildid() );
allyguild->_allyguild_serials.erase( obj_->_guildid );
// MuadDib Added to update online members when status changes.
obj_->update_online_members();
allyguild->update_online_members();
return new BLong( 1 );
}
return err;
}
case MTH_REMOVEENEMYGUILD:
{
if ( !ex.hasParams( 1 ) )
return new BError( "Not enough parameters" );
Core::Guild* enemyguild;
BError* err;
if ( getGuildParam( ex, 0, enemyguild, err ) )
{
if ( !obj_->_enemyguild_serials.count( enemyguild->guildid() ) )
return new BError( "That is not an enemy guild" );
obj_->_enemyguild_serials.erase( enemyguild->guildid() );
enemyguild->_enemyguild_serials.erase( obj_->_guildid );
// MuadDib Added to update online members when status changes.
obj_->update_online_members();
enemyguild->update_online_members();
return new BLong( 1 );
}
return err;
}
default:
{
bool changed = false;
return CallPropertyListMethod_id( obj_->_proplist, id, ex, changed );
}
}
}
BObjectImp* EGuildRefObjImp::call_polmethod( const char* methodname, UOExecutor& ex )
{
if ( obj_->_disbanded )
return new BError( "Guild has disbanded" );
bool forcebuiltin{ Executor::builtinMethodForced( methodname ) };
Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
if ( objmethod != nullptr )
return call_polmethod_id( objmethod->id, ex, forcebuiltin );
auto* res = Core::gamestate.system_hooks.call_script_method( methodname, &ex, this );
if ( res )
return res;
bool changed = false;
return CallPropertyListMethod( obj_->_proplist, methodname, ex, changed );
}
GuildExecutorModule::GuildExecutorModule( Bscript::Executor& exec )
: TmplExecutorModule<GuildExecutorModule, Core::PolModule>( exec )
{
}
2016-10-23 17:32:09 +02:00
/// ListGuilds returns an array of Guild objects
BObjectImp* GuildExecutorModule::mf_ListGuilds()
{
std::unique_ptr<ObjArray> result( new ObjArray );
for ( auto& itr : Core::gamestate.guilds )
{
Core::Guild* guild = itr.second.get();
result->addElement( new EGuildRefObjImp( Core::GuildRef( guild ) ) );
}
return result.release();
}
2016-10-23 17:32:09 +02:00
/// CreateGuild returns a new Guild object
BObjectImp* GuildExecutorModule::mf_CreateGuild()
{
Core::Guild* guild = new Core::Guild( Core::gamestate.nextguildid++ );
Core::gamestate.guilds[guild->guildid()].set( guild );
return new EGuildRefObjImp( ref_ptr<Core::Guild>( guild ) );
}
BObjectImp* GuildExecutorModule::mf_DestroyGuild()
{
Core::Guild* guild;
BError* err;
if ( getGuildParam( exec, 0, guild, err ) )
{
if ( guild->hasMembers() )
return new BError( "Guild has members" );
if ( guild->hasAllies() )
return new BError( "Guild has allies" );
if ( guild->hasEnemies() )
return new BError( "Guild has enemies" );
guild->disband();
Core::gamestate.guilds.erase( guild->guildid() );
return new BLong( 1 );
}
return err;
}
/// FindGuild( guildid );
BObjectImp* GuildExecutorModule::mf_FindGuild()
{
int guildid;
if ( getParam( 0, guildid ) )
{
Core::Guilds::iterator itr = Core::gamestate.guilds.find( guildid );
if ( itr != Core::gamestate.guilds.end() )
return new EGuildRefObjImp( ref_ptr<Core::Guild>( ( *itr ).second.get() ) );
return new BError( "Guild not found" );
2016-02-11 22:54:43 +01:00
}
return new BError( "Invalid parameter type" );
}
} // namespace Pol::Module