From eec6692ea4e481bc62e6e7b3648dc7e6eb7b087d Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Tue, 9 Jan 2024 02:48:45 +0800 Subject: [PATCH 1/7] Fix unhandled exception in UBoat::create_component --- pol-core/pol/multi/boat.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pol-core/pol/multi/boat.cpp b/pol-core/pol/multi/boat.cpp index db71fe3cfb..06f06f4b4a 100644 --- a/pol-core/pol/multi/boat.cpp +++ b/pol-core/pol/multi/boat.cpp @@ -1795,7 +1795,15 @@ void UBoat::create_components() end = bshape.Componentshapes.end(); itr != end; ++itr ) { - Items::Item* component = Items::Item::create( itr->objtype ); + Items::Item* component; + try + { + component = Items::Item::create( itr->objtype ); + } + catch ( ... ) + { + continue; + } if ( component == nullptr ) continue; // check boat members here From 9f35ee5a0c74c1ee615b763e590ae6608a2901d9 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Tue, 9 Jan 2024 02:52:10 +0800 Subject: [PATCH 2/7] Return 0 on unsuccessful boat move with MoveBoat and MoveBoatRelative --- docs/docs.polserver.com/pol100/boatem.xml | 4 ++-- pol-core/pol/module/boatmod.cpp | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/docs.polserver.com/pol100/boatem.xml b/docs/docs.polserver.com/pol100/boatem.xml index 0b04acf84e..a53f2a7120 100644 --- a/docs/docs.polserver.com/pol100/boatem.xml +++ b/docs/docs.polserver.com/pol100/boatem.xml @@ -19,7 +19,7 @@ Moves a boat in the direction of an absolute facing 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW speed to determine how fast the boat movement should be animated for smooth move - 1 always + 1 on success, 0 on failure none (returns 0 on invalid param) Boat @@ -44,7 +44,7 @@ Move a boat in the direction of a relative facing. Same as MoveBoat, but adjusted for boat's facing. If boat faces East, 0 will move E, 1 will move SE, etc. speed to determine how fast the boat movement should be animated for smooth move - 1 always + 1 on success, 0 on failure none (returns 0 on invalid param) Boat diff --git a/pol-core/pol/module/boatmod.cpp b/pol-core/pol/module/boatmod.cpp index ba64dc4b88..23f76d6448 100644 --- a/pol-core/pol/module/boatmod.cpp +++ b/pol-core/pol/module/boatmod.cpp @@ -35,8 +35,7 @@ Bscript::BObjectImp* UBoatExecutorModule::mf_MoveBoat() if ( getUBoatParam( 0, boat ) && getParam( 1, direction, 0, 7 ) && getParam( 2, speed, 1, 4 ) ) { Core::UFACING move_dir = static_cast( direction & 7 ); - boat->move( move_dir, static_cast( speed ), false ); - return new Bscript::BLong( 1 ); + return new Bscript::BLong( boat->move( move_dir, static_cast( speed ), false ) ); } return nullptr; } @@ -80,8 +79,7 @@ Bscript::BObjectImp* UBoatExecutorModule::mf_MoveBoatRelative() if ( getUBoatParam( 0, boat ) && getParam( 1, direction, 0, 7 ) && getParam( 2, speed, 1, 4 ) ) { Core::UFACING move_dir = static_cast( direction & 7 ); - boat->move( move_dir, static_cast( speed ), true ); - return new Bscript::BLong( 1 ); + return new Bscript::BLong( boat->move( move_dir, static_cast( speed ), true ) ); } return nullptr; } From 7495d52f88c60785bd112503d143adb9deb16c35 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Tue, 9 Jan 2024 02:58:08 +0800 Subject: [PATCH 3/7] Add boat.set_alternate_multiid --- .../docs.polserver.com/pol100/configfiles.xml | 3 ++- docs/docs.polserver.com/pol100/objref.xml | 1 + pol-core/bscript/objaccess.cpp | 1 + pol-core/bscript/objmethods.h | 1 + pol-core/pol/item/itemdesc.cpp | 13 +++++++++-- pol-core/pol/item/itemdesc.h | 2 ++ pol-core/pol/uoscrobj.cpp | 22 +++++++++++++++++++ 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/docs.polserver.com/pol100/configfiles.xml b/docs/docs.polserver.com/pol100/configfiles.xml index b7b08ee3da..7312fe6c2a 100644 --- a/docs/docs.polserver.com/pol100/configfiles.xml +++ b/docs/docs.polserver.com/pol100/configfiles.xml @@ -1568,7 +1568,8 @@ House (objtype) Boat (objtype) { {everything Item can have, plus: } - MultiID (int multiID number for this house) + MultiID (int multiID number for this house) + AlternateMultiID (int multiID number for alternative shape of boat, multiple can be supplied in order) } Map (objtype) diff --git a/docs/docs.polserver.com/pol100/objref.xml b/docs/docs.polserver.com/pol100/objref.xml index cfbbbe1f0c..7792d40554 100644 --- a/docs/docs.polserver.com/pol100/objref.xml +++ b/docs/docs.polserver.com/pol100/objref.xml @@ -386,6 +386,7 @@ + diff --git a/pol-core/bscript/objaccess.cpp b/pol-core/bscript/objaccess.cpp index b8e6536993..76373d3012 100644 --- a/pol-core/bscript/objaccess.cpp +++ b/pol-core/bscript/objaccess.cpp @@ -458,6 +458,7 @@ ObjMethod object_methods[] = { { MTH_SORTEDINSERT, "sorted_insert", false }, { MTH_SETUTF8STRING, "setutf8string", false }, { MTH_SET_PILOT, "set_pilot", false }, // 155 + { MTH_SET_ALTERNATE_MULTIID, "set_alternate_multiid", false } }; int n_objmethods = sizeof object_methods / sizeof object_methods[0]; ObjMethod* getKnownObjMethod( const char* token ) diff --git a/pol-core/bscript/objmethods.h b/pol-core/bscript/objmethods.h index b17bb0dd5a..22a3888d66 100644 --- a/pol-core/bscript/objmethods.h +++ b/pol-core/bscript/objmethods.h @@ -182,6 +182,7 @@ enum MethodID MTH_SORTEDINSERT, MTH_SETUTF8STRING, MTH_SET_PILOT, // 155 + MTH_SET_ALTERNATE_MULTIID }; diff --git a/pol-core/pol/item/itemdesc.cpp b/pol-core/pol/item/itemdesc.cpp index 16a619c1f4..f158938707 100644 --- a/pol-core/pol/item/itemdesc.cpp +++ b/pol-core/pol/item/itemdesc.cpp @@ -1055,17 +1055,26 @@ size_t MultiDesc::estimatedSize() const } BoatDesc::BoatDesc( u32 objtype, Clib::ConfigElem& elem, const Plib::Package* pkg ) - : MultiDesc( objtype, elem, BOATDESC, pkg ) + : MultiDesc( objtype, elem, BOATDESC, pkg ), alternates() { + u16 alternate; + alternates.push_back( multiid ); + while ( elem.remove_prop( "ALTERNATEMULTIID", &alternate ) ) + alternates.push_back( alternate ); } void BoatDesc::PopulateStruct( Bscript::BStruct* descriptor ) const { base::PopulateStruct( descriptor ); + std::unique_ptr a( new Bscript::ObjArray ); + for ( u16 alt : alternates ) + a->addElement( new Bscript::BLong( alt ) ); + + descriptor->addMember( "AlternateMultiID", a.release() ); } size_t BoatDesc::estimatedSize() const { - return base::estimatedSize(); + return base::estimatedSize() + alternates.capacity(); } HouseDesc::HouseDesc( u32 objtype, Clib::ConfigElem& elem, const Plib::Package* pkg ) diff --git a/pol-core/pol/item/itemdesc.h b/pol-core/pol/item/itemdesc.h index 970cbfc045..b7cf9ca2ff 100644 --- a/pol-core/pol/item/itemdesc.h +++ b/pol-core/pol/item/itemdesc.h @@ -266,6 +266,8 @@ class BoatDesc final : public MultiDesc virtual void PopulateStruct( Bscript::BStruct* descriptor ) const override; virtual ~BoatDesc(){}; virtual size_t estimatedSize() const override; + + std::vector alternates; }; class HouseDesc final : public MultiDesc diff --git a/pol-core/pol/uoscrobj.cpp b/pol-core/pol/uoscrobj.cpp index ff2b35d3f1..ed900289f8 100644 --- a/pol-core/pol/uoscrobj.cpp +++ b/pol-core/pol/uoscrobj.cpp @@ -4085,6 +4085,28 @@ BObjectImp* UBoat::script_method_id( const int id, Core::UOExecutor& ex ) return set_pilot( chr ); } } + case MTH_SET_ALTERNATE_MULTIID: + { + if ( ex.numParams() != 1 ) + return new BError( "Not enough parameters" ); + int index; + if ( !ex.getParam( 0, index ) ) + return new BError( "Invalid parameter type" ); + const auto& desc = static_cast( itemdesc() ); + if ( index < 0 || static_cast( index ) >= desc.alternates.size() ) + return new BError( "Index out of range" ); + + { + UBoat::BoatMoveGuard guard( this ); + u16 new_multiid = desc.alternates[index]; + u16 base_multi = multiid & ~3u; + u16 multioffset = multiid - base_multi; + multiid = new_multiid + multioffset; + } + transform_components( boatshape(), nullptr ); + send_display_boat_to_inrange(); + return new BLong( 1 ); + } default: return nullptr; } From 7d9f8d6daaa00d552727b3232c9532d86b705e78 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Tue, 9 Jan 2024 21:37:54 +0800 Subject: [PATCH 4/7] skip base multiid in alternates boat struct --- pol-core/pol/item/itemdesc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pol-core/pol/item/itemdesc.cpp b/pol-core/pol/item/itemdesc.cpp index f158938707..23f10ceaad 100644 --- a/pol-core/pol/item/itemdesc.cpp +++ b/pol-core/pol/item/itemdesc.cpp @@ -1067,8 +1067,10 @@ void BoatDesc::PopulateStruct( Bscript::BStruct* descriptor ) const { base::PopulateStruct( descriptor ); std::unique_ptr a( new Bscript::ObjArray ); - for ( u16 alt : alternates ) - a->addElement( new Bscript::BLong( alt ) ); + + // `alternates` contains the base multi id at index 0, so start at 1. + for ( size_t i = 1; i < alternates.size(); ++i ) + a->addElement( new Bscript::BLong( alternates[i] ) ); descriptor->addMember( "AlternateMultiID", a.release() ); } From d4f5b69103a49861113de37e74267d3536dc4600 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:28:39 +0800 Subject: [PATCH 5/7] Add test for boat.set_alternate_id --- pol-core/poltool/testfiles.cpp | 127 +++++++++--------- testsuite/pol/config/boats.cfg | 96 +++++++++++++ testsuite/pol/testpkgs/boat/itemdesc.cfg | 2 + .../pol/testpkgs/client/test_client_boat.src | 112 +++++++++++++++ testsuite/pol/uoconvert.cfg | 2 +- testsuite/testclient/pyuo/pyuo/packets.py | 2 - 6 files changed, 276 insertions(+), 65 deletions(-) diff --git a/pol-core/poltool/testfiles.cpp b/pol-core/poltool/testfiles.cpp index ae664571fb..b3a868a85c 100644 --- a/pol-core/poltool/testfiles.cpp +++ b/pol-core/poltool/testfiles.cpp @@ -540,68 +540,71 @@ void FileGenerator::modifyMultis( std::vector>& multis ) return e; }; multis.resize( 0x3fff, std::vector() ); - // first boat - multis[0x0] = std::vector{ - elem( 0x3edd, 0, 0, 0, 1 ), elem( 0x3e4e, 1, 4, 0, 0 ), elem( 0x3eae, 0, -4, 0, 0 ), - elem( 0x3eb2, 2, 0, 0, 0 ), elem( 0x3eb1, -2, 0, 0, 0 ), elem( 0x3eac, 0, -2, 0, 1 ), - elem( 0x3e9e, 1, -3, 0, 1 ), elem( 0x3ead, 0, -3, 0, 1 ), elem( 0x3e9d, -1, -3, 0, 1 ), - elem( 0x3eac, 1, -1, 0, 1 ), elem( 0x3ea1, -1, -1, 0, 1 ), elem( 0x3ea0, 1, -2, 0, 1 ), - elem( 0x3e9f, -1, -2, 0, 1 ), elem( 0x3eac, 0, -1, 0, 1 ), elem( 0x3ea1, -1, 0, 0, 1 ), - elem( 0x3eac, 1, 0, 0, 1 ), elem( 0x3e9c, 1, -4, 0, 1 ), elem( 0x3e9b, -1, -4, 0, 1 ), - elem( 0x3ee4, 2, -1, 0, 1 ), elem( 0x3eb1, -2, -1, 0, 1 ), elem( 0x3e9a, 0, -5, 0, 1 ), - elem( 0x3ede, 2, 0, 0, 1 ), elem( 0x3edc, -1, 1, 0, 1 ), elem( 0x3ea1, -1, 1, 0, 1 ), - elem( 0x3eac, 0, 1, 0, 1 ), elem( 0x3eac, 1, 1, 0, 1 ), elem( 0x3ea5, -1, 2, 0, 1 ), - elem( 0x3eac, 0, 2, 0, 1 ), elem( 0x3ea6, 1, 2, 0, 1 ), elem( 0x3eb2, 2, 1, 0, 1 ), - elem( 0x3eb1, -2, 1, 0, 1 ), elem( 0x3ece, -2, 2, 0, 1 ), elem( 0x3ea7, -1, 3, 0, 1 ), - elem( 0x3eac, 0, 3, 0, 1 ), elem( 0x3ea8, 1, 3, 0, 1 ), elem( 0x3eb6, -1, 4, 0, 1 ), - elem( 0x3eaa, 0, 4, 0, 1 ), elem( 0x3ebc, 0, 5, 0, 1 ), - }; - multis[0x1] = std::vector{ - elem( 0x3e5a, 0, 0, 0, 1 ), elem( 0x3e55, -4, 0, 0, 0 ), elem( 0x3e65, 4, 0, 0, 0 ), - elem( 0x3e85, 0, 2, 0, 0 ), elem( 0x3e8a, 0, -2, 0, 0 ), elem( 0x3e88, 0, -1, 0, 1 ), - elem( 0x3e8b, 1, 1, 0, 1 ), elem( 0x3e8b, -1, 1, 0, 1 ), elem( 0x3e8b, 0, 1, 0, 1 ), - elem( 0x3e8b, 1, 0, 0, 1 ), elem( 0x3e5b, 1, -1, 0, 1 ), elem( 0x3e88, 1, -1, 0, 1 ), - elem( 0x3e8b, -1, 0, 0, 1 ), elem( 0x3e88, -1, -1, 0, 1 ), elem( 0x3e8a, -1, -2, 0, 1 ), - elem( 0x3e8b, -2, 0, 0, 1 ), elem( 0x3e8d, -2, -1, 0, 1 ), elem( 0x3e59, 0, 2, 0, 1 ), - elem( 0x3e3f, -1, 2, 0, 1 ), elem( 0x3e7e, 2, 1, 0, 1 ), elem( 0x3e8a, 1, -2, 0, 1 ), - elem( 0x3e7f, 2, -1, 0, 1 ), elem( 0x3e8b, 2, 0, 0, 1 ), elem( 0x3e85, 1, 2, 0, 1 ), - elem( 0x3e8c, -2, 1, 0, 1 ), elem( 0x3e8b, 3, 0, 0, 1 ), elem( 0x3e7d, 3, -1, 0, 1 ), - elem( 0x3e90, -3, -1, 0, 1 ), elem( 0x3e8f, -3, 0, 0, 1 ), elem( 0x3e5c, 2, -2, 0, 1 ), - elem( 0x3e7c, 3, 1, 0, 1 ), elem( 0x3e8e, -3, 1, 0, 1 ), elem( 0x3e66, 4, 1, 0, 1 ), - elem( 0x3e67, 4, -1, 0, 1 ), elem( 0x3e91, -4, 1, 0, 1 ), elem( 0x3e94, -4, -1, 0, 1 ), - elem( 0x3e63, -5, 0, 0, 1 ), elem( 0x3e69, 5, 0, 0, 1 ), - }; - multis[0x2] = std::vector{ - elem( 0x3ee2, 0, 0, 0, 1 ), elem( 0x3e4b, 0, -4, 0, 0 ), elem( 0x3eb9, 0, 4, 0, 0 ), - elem( 0x3eb1, -2, 0, 0, 0 ), elem( 0x3eb2, 2, 0, 0, 0 ), elem( 0x3eac, 1, 0, 0, 1 ), - elem( 0x3eac, 1, -1, 0, 1 ), elem( 0x3eac, 1, 1, 0, 1 ), elem( 0x3eac, 0, 1, 0, 1 ), - elem( 0x3eac, 0, -1, 0, 1 ), elem( 0x3ee1, -1, 1, 0, 1 ), elem( 0x3ea1, -1, -1, 0, 1 ), - elem( 0x3ea1, -1, 0, 0, 1 ), elem( 0x3ea1, -1, 1, 0, 1 ), elem( 0x3eb1, -2, 1, 0, 1 ), - elem( 0x3eb1, -2, -1, 0, 1 ), elem( 0x3ea0, 1, -2, 0, 1 ), elem( 0x3e9f, -1, -2, 0, 1 ), - elem( 0x3eac, 0, -2, 0, 1 ), elem( 0x3ee3, 2, 0, 0, 1 ), elem( 0x3ee6, 2, -1, 0, 1 ), - elem( 0x3eb2, 2, 1, 0, 1 ), elem( 0x3ea6, 1, 2, 0, 1 ), elem( 0x3eac, 0, 2, 0, 1 ), - elem( 0x3ea5, -1, 2, 0, 1 ), elem( 0x3ead, 0, -3, 0, 1 ), elem( 0x3e9d, -1, -3, 0, 1 ), - elem( 0x3e9e, 1, -3, 0, 1 ), elem( 0x3ee0, -2, 2, 0, 1 ), elem( 0x3ea8, 1, 3, 0, 1 ), - elem( 0x3ea7, -1, 3, 0, 1 ), elem( 0x3eac, 0, 3, 0, 1 ), elem( 0x3eb6, -1, 4, 0, 1 ), - elem( 0x3eb5, 1, 4, 0, 1 ), elem( 0x3e9b, -1, -4, 0, 1 ), elem( 0x3e9c, 1, -4, 0, 1 ), - elem( 0x3eb4, 0, 5, 0, 1 ), elem( 0x3ec4, 0, -5, 0, 1 ), - }; - multis[0x3] = std::vector{ - elem( 0x3e6c, 0, 0, 0, 1 ), elem( 0x3e50, 4, 0, 0, 0 ), elem( 0x3e93, -4, 0, 0, 0 ), - elem( 0x3e8a, 0, -2, 0, 0 ), elem( 0x3e85, 0, 2, 0, 0 ), elem( 0x3e8b, 1, 1, 0, 1 ), - elem( 0x3e8b, -1, 1, 0, 1 ), elem( 0x3e8b, -1, 0, 0, 1 ), elem( 0x3e88, -1, -1, 0, 1 ), - elem( 0x3e6d, 1, -1, 0, 1 ), elem( 0x3e8b, 0, 1, 0, 1 ), elem( 0x3e88, 1, -1, 0, 1 ), - elem( 0x3e88, 0, -1, 0, 1 ), elem( 0x3e8b, 1, 0, 0, 1 ), elem( 0x3e8b, 2, 0, 0, 1 ), - elem( 0x3e7e, 2, 1, 0, 1 ), elem( 0x3e85, 1, 2, 0, 1 ), elem( 0x3e8a, 1, -2, 0, 1 ), - elem( 0x3e8a, -1, -2, 0, 1 ), elem( 0x3e8c, -2, 1, 0, 1 ), elem( 0x3e8b, -2, 0, 0, 1 ), - elem( 0x3e8d, -2, -1, 0, 1 ), elem( 0x3e6b, 0, 2, 0, 1 ), elem( 0x3e41, -1, 2, 0, 1 ), - elem( 0x3e7f, 2, -1, 0, 1 ), elem( 0x3e7d, 3, -1, 0, 1 ), elem( 0x3e8b, 3, 0, 0, 1 ), - elem( 0x3e7c, 3, 1, 0, 1 ), elem( 0x3e6e, 2, -2, 0, 1 ), elem( 0x3e8e, -3, 1, 0, 1 ), - elem( 0x3e8f, -3, 0, 0, 1 ), elem( 0x3e90, -3, -1, 0, 1 ), elem( 0x3e79, 4, 1, 0, 1 ), - elem( 0x3e7b, 4, -1, 0, 1 ), elem( 0x3e94, -4, -1, 0, 1 ), elem( 0x3e91, -4, 1, 0, 1 ), - elem( 0x3e76, 5, 0, 0, 1 ), elem( 0x3e95, -5, 0, 0, 1 ), - }; - // end first boat + for (int alternate_offset = 0; alternate_offset < 12; alternate_offset += 4) + { + // boat + multis[0x0 + alternate_offset] = std::vector{ + elem( 0x3edd, 0, 0, 0, 1 ), elem( 0x3e4e, 1, 4, 0, 0 ), elem( 0x3eae, 0, -4, 0, 0 ), + elem( 0x3eb2, 2, 0, 0, 0 ), elem( 0x3eb1, -2, 0, 0, 0 ), elem( 0x3eac, 0, -2, 0, 1 ), + elem( 0x3e9e, 1, -3, 0, 1 ), elem( 0x3ead, 0, -3, 0, 1 ), elem( 0x3e9d, -1, -3, 0, 1 ), + elem( 0x3eac, 1, -1, 0, 1 ), elem( 0x3ea1, -1, -1, 0, 1 ), elem( 0x3ea0, 1, -2, 0, 1 ), + elem( 0x3e9f, -1, -2, 0, 1 ), elem( 0x3eac, 0, -1, 0, 1 ), elem( 0x3ea1, -1, 0, 0, 1 ), + elem( 0x3eac, 1, 0, 0, 1 ), elem( 0x3e9c, 1, -4, 0, 1 ), elem( 0x3e9b, -1, -4, 0, 1 ), + elem( 0x3ee4, 2, -1, 0, 1 ), elem( 0x3eb1, -2, -1, 0, 1 ), elem( 0x3e9a, 0, -5, 0, 1 ), + elem( 0x3ede, 2, 0, 0, 1 ), elem( 0x3edc, -1, 1, 0, 1 ), elem( 0x3ea1, -1, 1, 0, 1 ), + elem( 0x3eac, 0, 1, 0, 1 ), elem( 0x3eac, 1, 1, 0, 1 ), elem( 0x3ea5, -1, 2, 0, 1 ), + elem( 0x3eac, 0, 2, 0, 1 ), elem( 0x3ea6, 1, 2, 0, 1 ), elem( 0x3eb2, 2, 1, 0, 1 ), + elem( 0x3eb1, -2, 1, 0, 1 ), elem( 0x3ece, -2, 2, 0, 1 ), elem( 0x3ea7, -1, 3, 0, 1 ), + elem( 0x3eac, 0, 3, 0, 1 ), elem( 0x3ea8, 1, 3, 0, 1 ), elem( 0x3eb6, -1, 4, 0, 1 ), + elem( 0x3eaa, 0, 4, 0, 1 ), elem( 0x3ebc, 0, 5, 0, 1 ), + }; + multis[0x1 + alternate_offset] = std::vector{ + elem( 0x3e5a, 0, 0, 0, 1 ), elem( 0x3e55, -4, 0, 0, 0 ), elem( 0x3e65, 4, 0, 0, 0 ), + elem( 0x3e85, 0, 2, 0, 0 ), elem( 0x3e8a, 0, -2, 0, 0 ), elem( 0x3e88, 0, -1, 0, 1 ), + elem( 0x3e8b, 1, 1, 0, 1 ), elem( 0x3e8b, -1, 1, 0, 1 ), elem( 0x3e8b, 0, 1, 0, 1 ), + elem( 0x3e8b, 1, 0, 0, 1 ), elem( 0x3e5b, 1, -1, 0, 1 ), elem( 0x3e88, 1, -1, 0, 1 ), + elem( 0x3e8b, -1, 0, 0, 1 ), elem( 0x3e88, -1, -1, 0, 1 ), elem( 0x3e8a, -1, -2, 0, 1 ), + elem( 0x3e8b, -2, 0, 0, 1 ), elem( 0x3e8d, -2, -1, 0, 1 ), elem( 0x3e59, 0, 2, 0, 1 ), + elem( 0x3e3f, -1, 2, 0, 1 ), elem( 0x3e7e, 2, 1, 0, 1 ), elem( 0x3e8a, 1, -2, 0, 1 ), + elem( 0x3e7f, 2, -1, 0, 1 ), elem( 0x3e8b, 2, 0, 0, 1 ), elem( 0x3e85, 1, 2, 0, 1 ), + elem( 0x3e8c, -2, 1, 0, 1 ), elem( 0x3e8b, 3, 0, 0, 1 ), elem( 0x3e7d, 3, -1, 0, 1 ), + elem( 0x3e90, -3, -1, 0, 1 ), elem( 0x3e8f, -3, 0, 0, 1 ), elem( 0x3e5c, 2, -2, 0, 1 ), + elem( 0x3e7c, 3, 1, 0, 1 ), elem( 0x3e8e, -3, 1, 0, 1 ), elem( 0x3e66, 4, 1, 0, 1 ), + elem( 0x3e67, 4, -1, 0, 1 ), elem( 0x3e91, -4, 1, 0, 1 ), elem( 0x3e94, -4, -1, 0, 1 ), + elem( 0x3e63, -5, 0, 0, 1 ), elem( 0x3e69, 5, 0, 0, 1 ), + }; + multis[0x2 + alternate_offset] = std::vector{ + elem( 0x3ee2, 0, 0, 0, 1 ), elem( 0x3e4b, 0, -4, 0, 0 ), elem( 0x3eb9, 0, 4, 0, 0 ), + elem( 0x3eb1, -2, 0, 0, 0 ), elem( 0x3eb2, 2, 0, 0, 0 ), elem( 0x3eac, 1, 0, 0, 1 ), + elem( 0x3eac, 1, -1, 0, 1 ), elem( 0x3eac, 1, 1, 0, 1 ), elem( 0x3eac, 0, 1, 0, 1 ), + elem( 0x3eac, 0, -1, 0, 1 ), elem( 0x3ee1, -1, 1, 0, 1 ), elem( 0x3ea1, -1, -1, 0, 1 ), + elem( 0x3ea1, -1, 0, 0, 1 ), elem( 0x3ea1, -1, 1, 0, 1 ), elem( 0x3eb1, -2, 1, 0, 1 ), + elem( 0x3eb1, -2, -1, 0, 1 ), elem( 0x3ea0, 1, -2, 0, 1 ), elem( 0x3e9f, -1, -2, 0, 1 ), + elem( 0x3eac, 0, -2, 0, 1 ), elem( 0x3ee3, 2, 0, 0, 1 ), elem( 0x3ee6, 2, -1, 0, 1 ), + elem( 0x3eb2, 2, 1, 0, 1 ), elem( 0x3ea6, 1, 2, 0, 1 ), elem( 0x3eac, 0, 2, 0, 1 ), + elem( 0x3ea5, -1, 2, 0, 1 ), elem( 0x3ead, 0, -3, 0, 1 ), elem( 0x3e9d, -1, -3, 0, 1 ), + elem( 0x3e9e, 1, -3, 0, 1 ), elem( 0x3ee0, -2, 2, 0, 1 ), elem( 0x3ea8, 1, 3, 0, 1 ), + elem( 0x3ea7, -1, 3, 0, 1 ), elem( 0x3eac, 0, 3, 0, 1 ), elem( 0x3eb6, -1, 4, 0, 1 ), + elem( 0x3eb5, 1, 4, 0, 1 ), elem( 0x3e9b, -1, -4, 0, 1 ), elem( 0x3e9c, 1, -4, 0, 1 ), + elem( 0x3eb4, 0, 5, 0, 1 ), elem( 0x3ec4, 0, -5, 0, 1 ), + }; + multis[0x3 + alternate_offset] = std::vector{ + elem( 0x3e6c, 0, 0, 0, 1 ), elem( 0x3e50, 4, 0, 0, 0 ), elem( 0x3e93, -4, 0, 0, 0 ), + elem( 0x3e8a, 0, -2, 0, 0 ), elem( 0x3e85, 0, 2, 0, 0 ), elem( 0x3e8b, 1, 1, 0, 1 ), + elem( 0x3e8b, -1, 1, 0, 1 ), elem( 0x3e8b, -1, 0, 0, 1 ), elem( 0x3e88, -1, -1, 0, 1 ), + elem( 0x3e6d, 1, -1, 0, 1 ), elem( 0x3e8b, 0, 1, 0, 1 ), elem( 0x3e88, 1, -1, 0, 1 ), + elem( 0x3e88, 0, -1, 0, 1 ), elem( 0x3e8b, 1, 0, 0, 1 ), elem( 0x3e8b, 2, 0, 0, 1 ), + elem( 0x3e7e, 2, 1, 0, 1 ), elem( 0x3e85, 1, 2, 0, 1 ), elem( 0x3e8a, 1, -2, 0, 1 ), + elem( 0x3e8a, -1, -2, 0, 1 ), elem( 0x3e8c, -2, 1, 0, 1 ), elem( 0x3e8b, -2, 0, 0, 1 ), + elem( 0x3e8d, -2, -1, 0, 1 ), elem( 0x3e6b, 0, 2, 0, 1 ), elem( 0x3e41, -1, 2, 0, 1 ), + elem( 0x3e7f, 2, -1, 0, 1 ), elem( 0x3e7d, 3, -1, 0, 1 ), elem( 0x3e8b, 3, 0, 0, 1 ), + elem( 0x3e7c, 3, 1, 0, 1 ), elem( 0x3e6e, 2, -2, 0, 1 ), elem( 0x3e8e, -3, 1, 0, 1 ), + elem( 0x3e8f, -3, 0, 0, 1 ), elem( 0x3e90, -3, -1, 0, 1 ), elem( 0x3e79, 4, 1, 0, 1 ), + elem( 0x3e7b, 4, -1, 0, 1 ), elem( 0x3e94, -4, -1, 0, 1 ), elem( 0x3e91, -4, 1, 0, 1 ), + elem( 0x3e76, 5, 0, 0, 1 ), elem( 0x3e95, -5, 0, 0, 1 ), + }; + // end boat + } multis[0x6b] = std::vector{ elem( 0x0066, -3, -3, 0, 1 ), elem( 0x0009, -3, -3, 7, 1 ), elem( 0x0064, -3, -2, 0, 1 ), elem( 0x0008, -3, -2, 7, 1 ), elem( 0x0064, -3, -1, 0, 1 ), elem( 0x0008, -3, -1, 7, 1 ), diff --git a/testsuite/pol/config/boats.cfg b/testsuite/pol/config/boats.cfg index db47217a5a..8bd683c6cf 100644 --- a/testsuite/pol/config/boats.cfg +++ b/testsuite/pol/config/boats.cfg @@ -49,3 +49,99 @@ Boat StarboardGangplankRetracted 0x3e8a 0 -2 0 Hold 0x3e93 -4 0 0 } + +# Small Boat Facing North +Boat +{ + MultiID 0x4 + TillerMan 0x3e4e 1 4 0 + PortGangplankExtended 0x3ed5 -2 0 0 + PortGangplankRetracted 0x3eb1 -2 0 0 + StarboardGangplankExtended 0x3ed4 2 0 0 + StarboardGangplankRetracted 0x3eb2 2 0 0 + Hold 0x3eae 0 -4 0 +} + +# Small Boat Facing East +Boat +{ + MultiID 0x5 + TillerMan 0x3e55 -4 0 0 + PortGangplankExtended 0x3e89 0 -2 0 + PortGangplankRetracted 0x3e8a 0 -2 0 + StarboardGangplankExtended 0x3e84 0 2 0 + StarboardGangplankRetracted 0x3e85 0 2 0 + Hold 0x3e65 4 0 0 +} + +# Small Boat Facing South +Boat +{ + MultiID 0x6 + TillerMan 0x3e4b 0 -4 0 + PortGangplankExtended 0x3ed4 2 0 0 + PortGangplankRetracted 0x3eb2 2 0 0 + StarboardGangplankExtended 0x3ed5 -2 0 0 + StarboardGangplankRetracted 0x3eb1 -2 0 0 + Hold 0x3eb9 0 4 0 +} + +# Small Boat Facing West +Boat +{ + MultiID 0x7 + TillerMan 0x3e50 4 0 0 + PortGangplankExtended 0x3e84 0 2 0 + PortGangplankRetracted 0x3e85 0 2 0 + StarboardGangplankExtended 0x3e89 0 -2 0 + StarboardGangplankRetracted 0x3e8a 0 -2 0 + Hold 0x3e93 -4 0 0 +} + +# Small Boat Facing North +Boat +{ + MultiID 0x8 + TillerMan 0x3e4e 1 4 0 + PortGangplankExtended 0x3ed5 -2 0 0 + PortGangplankRetracted 0x3eb1 -2 0 0 + StarboardGangplankExtended 0x3ed4 2 0 0 + StarboardGangplankRetracted 0x3eb2 2 0 0 + Hold 0x3eae 0 -4 0 +} + +# Small Boat Facing East +Boat +{ + MultiID 0x9 + TillerMan 0x3e55 -4 0 0 + PortGangplankExtended 0x3e89 0 -2 0 + PortGangplankRetracted 0x3e8a 0 -2 0 + StarboardGangplankExtended 0x3e84 0 2 0 + StarboardGangplankRetracted 0x3e85 0 2 0 + Hold 0x3e65 4 0 0 +} + +# Small Boat Facing South +Boat +{ + MultiID 0xa + TillerMan 0x3e4b 0 -4 0 + PortGangplankExtended 0x3ed4 2 0 0 + PortGangplankRetracted 0x3eb2 2 0 0 + StarboardGangplankExtended 0x3ed5 -2 0 0 + StarboardGangplankRetracted 0x3eb1 -2 0 0 + Hold 0x3eb9 0 4 0 +} + +# Small Boat Facing West +Boat +{ + MultiID 0xb + TillerMan 0x3e50 4 0 0 + PortGangplankExtended 0x3e84 0 2 0 + PortGangplankRetracted 0x3e85 0 2 0 + StarboardGangplankExtended 0x3e89 0 -2 0 + StarboardGangplankRetracted 0x3e8a 0 -2 0 + Hold 0x3e93 -4 0 0 +} diff --git a/testsuite/pol/testpkgs/boat/itemdesc.cfg b/testsuite/pol/testpkgs/boat/itemdesc.cfg index 2ca2c652d7..6f567800a0 100644 --- a/testsuite/pol/testpkgs/boat/itemdesc.cfg +++ b/testsuite/pol/testpkgs/boat/itemdesc.cfg @@ -39,6 +39,8 @@ Boat 0x11000 { Name SmallBoat MultiID 0x00 + AlternateMultiID 0x04 + AlternateMultiID 0x08 } Boat 0x11001 diff --git a/testsuite/pol/testpkgs/client/test_client_boat.src b/testsuite/pol/testpkgs/client/test_client_boat.src index 5670eeae98..afbb2b949f 100644 --- a/testsuite/pol/testpkgs/client/test_client_boat.src +++ b/testsuite/pol/testpkgs/client/test_client_boat.src @@ -1,6 +1,7 @@ use os; use uo; use boat; +use polsys; include "testutil"; include "communication"; @@ -446,3 +447,114 @@ exported function boat_bad_control_script_no_crash() DestroyMulti(boat2); return 1; endfunction + +exported function boat_alternate_multiid() + MoveBoatXY(boat,10,50); + var h:=getstandingheight(11,50, boat.z, boat.realm); + MoveObjectToLocation(char, 11,50,h.z); + while (!waitForClient(0, {EVT_OWNCREATE})) + endwhile + + var res; + + do + res := ensure_multiid(1, "Unexpected initial boat.multiid"); + + if (!res) + break; + endif + + res := boat.set_alternate_multiid(1); + + if (!res) + res := ret_error($"Unable to set_alternate_multiid(1): {res}"); + break; + endif + + res := ensure_multiid(5, "Unexpected first alternate boat.multiid"); + + if (!res) + break; + endif + + res := boat.set_alternate_multiid(2); + + if (!res) + res := ret_error($"Unable to set_alternate_multiid(2): {res}"); + break; + endif + + res := ensure_multiid(9, "Unexpected second alternate boat.multiid"); + + if (!res) + break; + endif + + res := boat.set_alternate_multiid(3); + + if (res != error) + res := ret_error($"Unexpected success for set_alternate_multiid(3): {res}"); + break; + endif + + res := ensure_multiid(9, "Unexpected change in boat.multiid after invalid boat.set_alternate_multiid(3)"); + + if (!res) + break; + endif + + res := boat.set_alternate_multiid(0); + + if (!res) + res := ret_error($"Unable to set_alternate_multiid(0): {res.errortext}"); + break; + endif + + res := ensure_multiid(1, "Unexpected base boat.multiid"); + + if (!res) + break; + endif + + res := 1; + dowhile (0); + + return res; +endfunction + +function ensure_multiid(multiid, errormsg) + if (boat.multiid != multiid) + return ret_error($"{errormsg}, expected {multiid} != actual {boat.multiid}"); + endif + + Clear_Event_Queue(); + + clientcon.sendevent(struct{todo:="list_objects", id:=0}); + while (1) + var res:=waitForClient(0, {EVT_LIST_OBJS}); + if (!res) + return res; + endif + + foreach obj in (res.objs) + if (obj.serial == boat.serial) + if (obj.graphic != multiid) + return ret_error("client boat.graphic mismatch, expected {multiid} != actual {obj.graphic}"); + else + return 1; + endif + endif + endforeach + break; + endwhile + return ret_error("client object list does not contain boat"); +endfunction + +exported function boat_alternate_multiid_itemdesc() + var AlternateMultiID := GetItemDescriptor(0x11000).AlternateMultiID; + if (!((4 in AlternateMultiID) && (8 in AlternateMultiID) && (Len(AlternateMultiID) == 2))) + return ret_error("Expected AlternateMultiID to be { 4, 8 }, got " + AlternateMultiID); + endif + + return 1; +endfunction diff --git a/testsuite/pol/uoconvert.cfg b/testsuite/pol/uoconvert.cfg index cdbaf04f1a..ce8a7b00f7 100644 --- a/testsuite/pol/uoconvert.cfg +++ b/testsuite/pol/uoconvert.cfg @@ -18,7 +18,7 @@ TileOptions MultiTypes { - Boats 0x0 0x1 0x2 0x3 + Boats 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb // dummy Houses 0xffff // dummy diff --git a/testsuite/testclient/pyuo/pyuo/packets.py b/testsuite/testclient/pyuo/pyuo/packets.py index b2bfa9e507..1176b319b3 100644 --- a/testsuite/testclient/pyuo/pyuo/packets.py +++ b/testsuite/testclient/pyuo/pyuo/packets.py @@ -1650,13 +1650,11 @@ class MultipleNewObjectInfoPacket(Packet): def decodeChild(self): self.length = self.dushort() - self.log.info('got length {}'.format(self.length)) self.count = self.dushort() self.packets = [] for _ in range(0, self.count): pkt = NewObjectInfoPacket() pkt.decode(self.rpb(pkt.length)) - self.log.info("got packet for item {}".format(pkt.serial)) self.packets.append(pkt) class HealthBarStatusUpdate(Packet): From a12a776ca3c3ee0cbb995155e95b587ee94819d4 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:39:22 +0800 Subject: [PATCH 6/7] docs, core-changes --- docs/docs.polserver.com/pol100/configfiles.xml | 3 ++- docs/docs.polserver.com/pol100/corechanges.xml | 7 ++++++- pol-core/doc/core-changes.txt | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/docs.polserver.com/pol100/configfiles.xml b/docs/docs.polserver.com/pol100/configfiles.xml index 7312fe6c2a..fce9eafe2a 100644 --- a/docs/docs.polserver.com/pol100/configfiles.xml +++ b/docs/docs.polserver.com/pol100/configfiles.xml @@ -1568,7 +1568,7 @@ House (objtype) Boat (objtype) { {everything Item can have, plus: } - MultiID (int multiID number for this house) + MultiID (int multiID number for this boat) AlternateMultiID (int multiID number for alternative shape of boat, multiple can be supplied in order) } @@ -1624,6 +1624,7 @@ Armor (objtype) Spellbook: Recognized scroll objects are: Magic: 0x1F2D - 0x1F6C, Necro 0x2260 - 0x226F, Paladin: 0x2270 - 0x227C, Bushido: 0x238D - 0x2392, Ninjitsu: 0x23A1 - 0x23A8, SpellWeaving: 0x2D51 - 0x2D60. The list of spellids for spells.cfg is now as follows: Magery = 1+, Necro = 101+, Paladin = 201+, Bushido = 401+, Ninjitsu = 501+, SpellWeaving = 601+. Sorry this is hardcoded :P Cursed: Note that cursed gold coins (objtype 0x0EED) are still usable for commerce transactions with vendors in the core. 'Unspendable' cursed gold coins should be defined in a separate itemdesc entry with a different objtype using the same graphic as gold coins (0x0EED) with Cursed set to 1. Weapon: If Delay != 0 Core will use it to calculate Weapon speed. Speed Entry is optional ONLY if Delay is populated. + AlternateMultiID: Specifies additional MultiIDs that can be used to switch a boat's graphic via boat method set_alternate_multiid(). spells.cfg stacking.cfg diff --git a/docs/docs.polserver.com/pol100/corechanges.xml b/docs/docs.polserver.com/pol100/corechanges.xml index 4724d792ef..4cefb3bcb2 100644 --- a/docs/docs.polserver.com/pol100/corechanges.xml +++ b/docs/docs.polserver.com/pol100/corechanges.xml @@ -2,9 +2,14 @@
Latest Core Changes - 01-09-2024 + 01-10-2024
+ + 01-10-2024 + Kevin: + Boat item descriptor `AlternateMultiID` and boat method `boat.set_alternate_multiid(position)` to facilitate changing a boat's graphic, for example switching a boat from a "normal" to a "damaged" graphic. + 01-07-2024 Kevin: diff --git a/pol-core/doc/core-changes.txt b/pol-core/doc/core-changes.txt index 07d7021a12..bb8cfb212f 100644 --- a/pol-core/doc/core-changes.txt +++ b/pol-core/doc/core-changes.txt @@ -1,4 +1,6 @@ -- POL100.1.0 -- +01-10-2024 Kevin: + Added: Boat item descriptor `AlternateMultiID` and boat method `boat.set_alternate_multiid(position)` to facilitate changing a boat's graphic, for example switching a boat from a "normal" to a "damaged" graphic. 01-07-2024 Kevin: Added: Boat control script can be specified via the `ControlScript` item descriptor. If none specified, defaults to existing `scripts/misc/boat.ecl`. Fixed: Shard no longer crashes if boat control script does not exist. From 25e11e70b876bfb30066a24a85d7a50074080785 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:22:07 +0800 Subject: [PATCH 7/7] use array equals in test --- testsuite/pol/testpkgs/client/test_client_boat.src | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testsuite/pol/testpkgs/client/test_client_boat.src b/testsuite/pol/testpkgs/client/test_client_boat.src index afbb2b949f..87ef2f9780 100644 --- a/testsuite/pol/testpkgs/client/test_client_boat.src +++ b/testsuite/pol/testpkgs/client/test_client_boat.src @@ -551,9 +551,10 @@ function ensure_multiid(multiid, errormsg) endfunction exported function boat_alternate_multiid_itemdesc() - var AlternateMultiID := GetItemDescriptor(0x11000).AlternateMultiID; - if (!((4 in AlternateMultiID) && (8 in AlternateMultiID) && (Len(AlternateMultiID) == 2))) - return ret_error("Expected AlternateMultiID to be { 4, 8 }, got " + AlternateMultiID); + var actual := GetItemDescriptor(0x11000).AlternateMultiID; + var expected := array{4, 8}; + if (actual != expected) + return ret_error($"Expected AlternateMultiID to be {expected}, got {actual}"); endif return 1;