17 #include <boost/numeric/conversion/cast.hpp> 20 #include <format/format.h> 21 #include "../../bscript/berror.h" 22 #include "../../bscript/executor.h" 23 #include "../../bscript/objmembers.h" 24 #include "../../bscript/objmethods.h" 25 #include "../../clib/cfgelem.h" 26 #include "../../clib/clib_endian.h" 27 #include "../../clib/logfacility.h" 28 #include "../../clib/passert.h" 29 #include "../../clib/refptr.h" 30 #include "../../clib/streamsaver.h" 31 #include "../../plib/mapcell.h" 32 #include "../../plib/mapshape.h" 33 #include "../../plib/systemstate.h" 35 #include "../fnsearch.h" 36 #include "../globals/object_storage.h" 37 #include "../item/itemdesc.h" 38 #include "../mobile/charactr.h" 39 #include "../module/osmod.h" 40 #include "../module/uomod.h" 41 #include "../network/cgdata.h" 42 #include "../network/client.h" 43 #include "../realms/realm.h" 44 #include "../scrdef.h" 45 #include "../scrsched.h" 46 #include "../scrstore.h" 47 #include "../uconst.h" 49 #include "../uobject.h" 50 #include "../uoexec.h" 51 #include "../uoexhelp.h" 52 #include "../uoscrobj.h" 53 #include "../uworld.h" 66 short x1 = house->
x + md.
minrx, y1 = house->
y + md.
minry;
67 short x2 = house->
x + md.
maxrx, y2 = house->
y + md.
maxry;
71 UMulti* multi = house->realm->find_supporting_multi( chr->x, chr->y, chr->z );
72 if ( const_cast<const UMulti*>( multi ) == house )
73 chrs_in.push_back( chr );
77 UMulti* multi = house->realm->find_supporting_multi( item->x, item->y, item->z );
78 if ( const_cast<const UMulti*>( multi ) == house )
80 if ( Core::tile_flags( item->graphic ) & Plib::FLAG::WALKBLOCK )
81 items_in.push_front( item );
83 items_in.push_back( item );
91 waiting_for_accept( false ),
92 editing_floor_num( 1 ),
120 for (
unsigned i = 0; i < md.
elems.size(); ++i )
128 "Couldn't add newly created item as house component. Please report this " 129 "bug on the forums." );
154 newx = boost::numeric_cast<
u16>(
x + xoff );
155 newy = boost::numeric_cast<
u16>(
y + yoff );
156 newz = boost::numeric_cast<
s8>(
z + zoff );
158 catch ( boost::bad_numeric_cast& )
162 POLLOG_ERROR <<
"Out-of-range coordinates while trying to add Item " 163 << fmt::hexu( item->
serial ) <<
" to House " << fmt::hexu(
serial ) <<
'\n';
206 if ( item !=
nullptr && !item->
orphan() )
211 return arr.release();
220 for (
auto& item : itemlist )
228 return arr.release();
237 for (
auto& chr : moblist )
241 return arr.release();
251 using namespace Bscript;
278 return new BError(
"House is not custom" );
280 return new BError(
"House is currently been edited" );
292 if ( objmember !=
nullptr )
300 using namespace Bscript;
302 if ( imp !=
nullptr )
313 return new BLong( 1 );
329 return new BLong( 1 );
332 return new BError(
"Item is already an house component" );
334 return new BError(
"Couldn't add component" );
349 Components::iterator pos;
353 iref->house(
nullptr );
357 return new BError(
"Component not found" );
358 return new BLong( 1 );
366 return new BError(
"House is not custom" );
368 return new BError(
"House is currently been edited" );
370 return new BError(
"Not enough parameters" );
372 int xoff, yoff, item_z;
380 elem.
z =
static_cast<u8>( item_z );
385 std::vector<u8> newvec;
387 std::vector<u8> newvec2;
391 return new BLong( 1 );
398 return new BError(
"House is not custom" );
400 return new BError(
"House is currently been edited" );
402 return new BError(
"Not enough parameters" );
403 int item_graphic, xoff, yoff, item_z;
409 static_cast<u32>( yoff ), static_cast<u8>( item_z ) );
414 std::vector<u8> newvec;
416 std::vector<u8> newvec2;
420 return new BLong( ret ? 1 : 0 );
427 return new BError(
"House is not custom" );
431 return new BError(
"House is currently not waiting for a commit" );
433 return new BError(
"Not enough parameters" );
439 return new BLong( 1 );
446 return new BError(
"House is not custom" );
448 return new BError(
"House is currently not been edited" );
450 return new BError(
"Not enough parameters" );
458 return new BError(
"Character is not editing this house" );
459 return new BLong( 1 );
467 return new BError(
"Invalid parameter type" );
473 if ( objmethod !=
nullptr )
485 while ( elem.
remove_prop(
"Component", &tmp_serial ) )
488 if ( item !=
nullptr )
493 os <<
"Couldn't add component " << fmt::hexu( item->
serial ) <<
" to house " 494 << fmt::hexu(
serial ) <<
".\n";
495 UHouse* contHouse = item->house();
496 if ( contHouse ==
nullptr )
498 os <<
"This is probably a core bug. Please report it on the forums.";
502 os <<
"This item is already part of house " << contHouse->
serial <<
".\n";
503 os <<
"Allowing an item to be a component in two different houses was a bug,\n";
504 os <<
"please also fix your save data.";
506 throw std::runtime_error( os.str() );
513 short ysize, xsize, xbase, ybase;
517 xbase = (short)abs( def.
minrx );
518 ybase = (short)abs( def.
minry );
543 if ( item !=
nullptr && !item->
orphan() )
545 sw() <<
"\tComponent\t0x" << fmt::hex( item->
serial ) <<
pf_endl;
564 POLLOG.Format(
"Destroying component 0x{:X}, serial=0x{:X}\n" )
569 POLLOG <<
"Component destroyed\n";
581 HouseFloorZColumn::iterator itr;
588 if ( shape_x + design->
xoff < 0 || shape_x + design->
xoff >= static_cast<s32>( design->
width ) ||
589 shape_y + design->
yoff < 0 || shape_y + design->
yoff >= static_cast<s32>( design->
height ) )
594 for ( itr = elems->begin(); itr != elems->end(); ++itr )
597 shape.
z = itr->z + zbase;
605 vec.push_back( shape );
619 HouseFloorZColumn::iterator itr;
626 if ( obj_x + design->
xoff < 0 || obj_x + design->
xoff >= static_cast<s32>( design->
width ) ||
627 obj_y + design->
yoff < 0 || obj_y + design->
yoff >= static_cast<s32>( design->
height ) )
632 for ( itr = elems->begin(); itr != elems->end(); ++itr )
634 Core::StaticRec rec( itr->graphic, static_cast<signed char>( itr->z + zbase ),
641 vec.push_back( rec );
653 if ( chr ==
nullptr )
655 if ( chr->
client ==
nullptr )
661 if ( multi ==
nullptr )
665 if ( house ==
nullptr )
672 bool multis_exist_in(
unsigned short mywest,
unsigned short mynorth,
unsigned short myeast,
679 for (
unsigned short wx = wxL; wx <=
wxH; ++wx )
681 for (
unsigned short wy = wyL; wy <=
wyH; ++wy )
683 for (
const auto& multi : realm->
zone[wx][wy].
multis )
685 const MultiDef& edef = multi->multidef();
687 unsigned short itswest, itseast, itsnorth, itssouth;
689 itswest =
static_cast<unsigned short>( multi->x + edef.
minrx );
690 itseast =
static_cast<unsigned short>( multi->x + edef.
maxrx );
691 itsnorth =
static_cast<unsigned short>( multi->y + edef.
minry );
692 itssouth =
static_cast<unsigned short>( multi->y + edef.
maxry );
694 if ( mynorth >= itsnorth && mynorth <= itssouth )
696 if ( ( mywest >= itswest && mywest <= itseast ) ||
697 ( myeast >= itswest && myeast <= itseast ) )
702 if ( mysouth >= itsnorth && mysouth <= itssouth )
704 if ( ( mywest >= itswest && mywest <= itseast ) ||
705 ( myeast >= itswest && myeast <= itseast ) )
711 if ( itsnorth >= mynorth && itsnorth <= mysouth )
713 if ( ( itswest >= mywest && itswest <= myeast ) ||
714 ( itseast >= mywest && itseast <= myeast ) )
719 if ( itssouth >= mynorth && itssouth <= mysouth )
721 if ( ( itswest >= mywest && itswest <= myeast ) ||
722 ( itseast >= mywest && itseast <= myeast ) )
733 bool objects_exist_in(
unsigned short x1,
unsigned short y1,
unsigned short x2,
unsigned short y2,
740 if ( obj->x >= x1 && obj->x <= x2 && obj->y >= y1 && obj->y <= y2 )
746 for (
unsigned short wx = wxL; wx <=
wxH; ++wx )
748 for (
unsigned short wy = wyL; wy <=
wyH; ++wy )
752 if ( includes( chr ) )
755 for (
const auto& chr : realm->
zone[wx][wy].
npcs )
757 if ( includes( chr ) )
760 for (
const auto& item : realm->
zone[wx][wy].
items )
762 if ( includes( item ) )
773 for (
unsigned short x = x1;
x <= x2; ++
x )
775 for (
unsigned short y = y1;
y <= y2; ++
y )
782 POLLOG.Format(
"Refusing to place house at {},{},{}: can't stand there\n" ) <<
x <<
y <<
z;
785 if ( labs( z - newz ) > 2 )
787 POLLOG.Format(
"Refusing to place house at {},{},{}: result Z ({}) is too far afield\n" )
788 <<
x <<
y << z << newz;
814 y + md->
maxry + 5, realm ) )
816 return new Bscript::BError(
"Location intersects with another structure" );
830 y + md->
maxry + 1, z, flags, realm ) )
862 for (
unsigned short xd = 0; xd < 5; ++xd )
864 for (
unsigned short yd = 0; yd < 5; ++yd )
869 unsigned short sx = item->
x;
870 unsigned short sy = item->
y;
873 bool res = item->
realm->
walkheight( sx + xd, sy + yd, item->
z, &newz, &multi, &walkon,
true,
879 move_item( item, item->
x + xd, item->
y + yd, static_cast<signed char>( newz ),
nullptr );
887 move_item( item, item->
x, item->
y, static_cast<signed char>( newz ),
nullptr );
914 while ( !item_contents.empty() )
919 item_contents.pop_front();
922 while ( !chr_contents.empty() )
927 chr_contents.pop_back();
939 if ( !obj->ismobile() )
973 if ( prog.
get() != nullptr )
977 if ( prog->haveProgram )
986 ex->os_module->priority = 100;
988 if ( ex->setProgram( prog.
get() ) )
1007 std::vector<u8> newvec;
1019 if ( chr && chr->
client )
Core::UObjectRef Squatter
static Item * create(u32 objtype, u32 serial=0)
CustomHouseDesign WorkingDesign
virtual void register_object(Core::UObject *obj) POL_OVERRIDE
virtual void walk_on(Mobile::Character *chr) POL_OVERRIDE
unsigned int tile_flags(unsigned short tilenum)
std::list< CUSTOM_HOUSE_ELEMENT > HouseFloorZColumn
void add_component_no_check(Component item)
ref_ptr< Bscript::EScriptProgram > find_script2(const ScriptDef &script, bool complain_if_not_found, bool cache_script)
void Add(CUSTOM_HOUSE_ELEMENT &elem)
const int CRMULTI_IGNORE_OBJECTS
std::list< Items::Item * > ItemList
virtual Bscript::BObjectImp * script_method_id(const int id, Bscript::Executor &ex) POL_OVERRIDE
virtual Bscript::BObjectImp * script_method_id(const int id, Bscript::Executor &ex) POL_OVERRIDE
void add_item_to_world(Items::Item *item)
std::vector< StaticRec > StaticList
Bscript::ObjArray * items_list() const
BApplicObjType eitemrefobjimp_type
virtual Bscript::BObjectImp * script_method(const char *membername, Bscript::Executor &ex) POL_OVERRIDE
static void list_contents(const UHouse *house, ItemList &items_in, MobileList &chrs_in)
static UHouse * FindWorkingHouse(u32 chrserial)
void SetCustom(bool custom)
#define RANGE_VISUAL_LARGE_BUILDINGS
virtual void unregister_object(Core::UObject *obj) POL_OVERRIDE
virtual Bscript::BObjectImp * get_script_member(const char *membername) const POL_OVERRIDE
bool walkheight(unsigned short x, unsigned short y, short oldz, short *newz, Multi::UMulti **pmulti, Items::Item **pwalkon, bool doors_block, Core::MOVEMODE movemode, short *gradual_boost=nullptr)
const int CRMULTI_IGNORE_MULTIS
Items::Item * find_toplevel_item(u32 serial)
UObject(u32 objtype, UOBJ_CLASS uobj_class)
ObjMember * getKnownObjMember(const char *token)
bool move_character_to(Mobile::Character *chr, unsigned short x, unsigned short y, short z, int flags, Realms::Realm *oldrealm)
virtual void printProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
std::list< Mobile::Character * > MobileList
Bscript::ObjArray * component_list() const
CustomHouseDesign CurrentDesign
void send_multi_to_inrange(const Multi::UMulti *multi)
Bscript::ObjArray * list_parts() const
HouseFloorZColumn * GetElementsAt(s32 xoffset, s32 yoffset)
std::vector< u8 > CurrentCompressed
bool multis_exist_in(unsigned short mywest, unsigned short mynorth, unsigned short myeast, unsigned short mysouth, Realms::Realm *realm)
CustomHouseDesign BackupDesign
ObjMethod * getKnownObjMethod(const char *token)
void CustomHouseStopEditing(Mobile::Character *chr, UHouse *house)
const ItemDesc & find_itemdesc(unsigned int objtype)
void AddComponents(UHouse *house)
void add_multi_to_world(Multi::UMulti *multi)
static Bscript::BObjectImp * scripted_create(const Items::ItemDesc &descriptor, u16 x, u16 y, s8 z, Realms::Realm *realm, int flags)
virtual bool readshapes(Plib::MapShapeList &vec, short shape_x, short shape_y, short zbase) POL_OVERRIDE
ZoneCharacters characters
std::string hexint(unsigned short v)
virtual void readProperties(Clib::ConfigElem &elem) POL_OVERRIDE
bool EraseGraphicAt(u16 graphic, u32 xoffset, u32 yoffset, u8 z)
virtual size_t estimatedSize() const POL_OVERRIDE
void zone_convert_clip(int x, int y, const Realms::Realm *realm, unsigned short *wx, unsigned short *wy)
size_t estimatedSize() const
bool getCharacterParam(Bscript::Executor &exec, unsigned param, Mobile::Character *&chrptr)
virtual bool readobjects(Core::StaticList &vec, short obj_x, short obj_y, short zbase) POL_OVERRIDE
bool objects_exist_in(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, Realms::Realm *realm)
Multi::UMulti * system_find_multi(u32 serial)
virtual Bscript::BObjectImp * get_script_member_id(const int id) const POL_OVERRIDE
id test
Bscript::ObjArray * mobiles_list() const
virtual class UHouse * as_house()
void destroy_item(Item *item)
Bscript::BObjectImp * destroy_house(UHouse *house)
UOExecutor * create_script_executor()
void InitDesign(u32 _height, u32 _width, s32 xoffset, s32 yoffset)
u32 GetNewItemSerialNumber(void)
Core::ScriptDef walk_on_script
void printProperties(Clib::StreamWriter &sw, const std::string &prefix) const
const int CRMULTI_IGNORE_FLATNESS
void set_decay_after(unsigned int seconds)
void CustomHousesQuit(Mobile::Character *chr, bool drop_changes)
bool statics_cause_problems(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, s8 z, int, Realms::Realm *realm)
std::vector< MULTI_ELEM > elems
char tileheight(unsigned short tilenum)
void AcceptHouseCommit(Mobile::Character *chr, bool accept)
UHouse(const Items::ItemDesc &itemdesc)
virtual void readProperties(Clib::ConfigElem &elem) POL_OVERRIDE
void send_remove_object_to_inrange(const UObject *centerObject)
Mobile::Character * find_character(u32 serial)
void move_item(Item *item, UFACING facing)
#define passert_always_r(exp, reason)
bool cache_interactive_scripts
void CustomHousesSendFullToInRange(UHouse *house, int design, int range)
void destroy_components()
bool Insert(UObject *obj)
virtual Bscript::BObjectImp * get_script_member_id(const int id) const POL_OVERRIDE
id test
const int MOVEITEM_FORCELOCATION
bool remove_prop(const char *propname, std::string *value)
void restart_decay_timer()
BApplicObjBase * getApplicObjParam(unsigned param, const BApplicObjType *object_type)
std::vector< u8 > WorkingCompressed
virtual size_t estimatedSize() const POL_OVERRIDE
ObjectStorageManager objStorageManager
bool groundheight(unsigned short x, unsigned short y, short *z) const
virtual void printProperties(Clib::StreamWriter &sw) const POL_OVERRIDE
CustomHouseElements Elements[CUSTOM_HOUSE_NUM_PLANES]
unsigned short remove_ushort(const char *propname)
virtual class UHouse * as_house() POL_OVERRIDE
bool hasParams(unsigned howmany) const
bool can_add_component(const Items::Item *item)
void move_to_ground(Items::Item *item)
virtual Bscript::BObjectImp * make_ref() POL_OVERRIDE
void schedule_executor(UOExecutor *ex)
const MultiDef & multidef() const
void CustomHousesSendFull(UHouse *house, Network::Client *client, int design)
bool valid(unsigned short x, unsigned short y, short z) const
const ItemDesc & itemdesc() const
void remove_multi_from_world(Multi::UMulti *multi)
#define CUSTOM_HOUSE_NUM_PLANES
bool IsWaitingForAccept() const
void readProperties(Clib::ConfigElem &elem, const std::string &prefix)
bool remove_bool(const char *propname)
bool add_component(Items::Item *item, s32 xoff, s32 yoff, s16 zoff)
const MultiDef * MultiDefByMultiID(u16 multiid)
static void ClearComponents(UHouse *house)
void update_item_to_inrange(const Item *item)
bool getParam(unsigned param, int &value)
static void InBox(u16 x1, u16 y1, u16 x2, u16 y2, const Realms::Realm *realm, F &&f)