Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add boat.set_alternate_multiid #593

Merged
merged 7 commits into from Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/docs.polserver.com/pol100/boatem.xml
Expand Up @@ -19,7 +19,7 @@
<explain>Moves a boat in the direction of an absolute facing</explain>
<explain>0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW</explain>
<explain>speed to determine how fast the boat movement should be animated for smooth move</explain>
<return>1 always</return>
<return>1 on success, 0 on failure</return>
<error>none (returns 0 on invalid param)</error>
<related>Boat</related>
</function>
Expand All @@ -44,7 +44,7 @@
<explain>Move a boat in the direction of a relative facing. Same as MoveBoat, but adjusted for boat's facing.</explain>
<explain>If boat faces East, 0 will move E, 1 will move SE, etc.</explain>
<explain>speed to determine how fast the boat movement should be animated for smooth move</explain>
<return>1 always</return>
<return>1 on success, 0 on failure</return>
<error>none (returns 0 on invalid param)</error>
<related>Boat</related>
</function>
Expand Down
4 changes: 3 additions & 1 deletion docs/docs.polserver.com/pol100/configfiles.xml
Expand Up @@ -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 boat)
AlternateMultiID (int multiID number for alternative shape of boat, multiple can be supplied in order)
}

Map (objtype)
Expand Down Expand Up @@ -1623,6 +1624,7 @@ Armor (objtype)
<explain>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</explain>
<explain>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.</explain>
<explain>Weapon: If Delay != 0 Core will use it to calculate Weapon speed. Speed Entry is optional ONLY if Delay is populated.</explain>
<explain>AlternateMultiID: Specifies additional MultiIDs that can be used to switch a boat's graphic via boat method set_alternate_multiid().</explain>
<related>spells.cfg</related>
<related>stacking.cfg</related>
</cfgfile>
Expand Down
7 changes: 6 additions & 1 deletion docs/docs.polserver.com/pol100/corechanges.xml
Expand Up @@ -2,9 +2,14 @@
<ESCRIPT>
<header>
<topic>Latest Core Changes</topic>
<datemodified>01-09-2024</datemodified>
<datemodified>01-10-2024</datemodified>
</header>
<version name="POL100.1.0">
<entry>
<date>01-10-2024</date>
<author>Kevin:</author>
<change type="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 &quot;normal&quot; to a &quot;damaged&quot; graphic.</change>
</entry>
<entry>
<date>01-07-2024</date>
<author>Kevin:</author>
Expand Down
1 change: 1 addition & 0 deletions docs/docs.polserver.com/pol100/objref.xml
Expand Up @@ -386,6 +386,7 @@

<method proto="move_offline_mobiles(int x, int y, int z[, string realm])" returns="true/false" desc="moves offline mobiles on boat to x,y,z. If realm is not set, Boat-realm is used." />
<method proto="set_pilot(Character | 0)" returns="true/false" desc="Sets the boat pilot to the provided character; removes pilot if `0` is passed. Mouse movements from the boat's pilot will be sent to the boat's control script. See event SYSEVENT_BOAT_MOVEMENT for more details. Possible errors: The boat is already being piloted; The boat does not have a running process; That character is not connected; The boat does not have that character on it; The boat mount piece is not equippable by that character; The client for that character does not support High Seas Adventure" />
<method proto="set_alternate_multiid(int)" returns="true/error" desc="Used to change a boat's multi to an alternative multi defined in its itemdesc file. Alternate ids are referenced with an integer based on the order they are defined in the itemdesc file starting from 1, with the base multi id being 0."/>
</class>


Expand Down
1 change: 1 addition & 0 deletions pol-core/bscript/objaccess.cpp
Expand Up @@ -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 )
Expand Down
1 change: 1 addition & 0 deletions pol-core/bscript/objmethods.h
Expand Up @@ -182,6 +182,7 @@ enum MethodID
MTH_SORTEDINSERT,
MTH_SETUTF8STRING,
MTH_SET_PILOT, // 155
MTH_SET_ALTERNATE_MULTIID
};


Expand Down
2 changes: 2 additions & 0 deletions 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.
Expand Down
15 changes: 13 additions & 2 deletions pol-core/pol/item/itemdesc.cpp
Expand Up @@ -1055,17 +1055,28 @@ 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<Bscript::ObjArray> a( new Bscript::ObjArray );

// `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() );
}
size_t BoatDesc::estimatedSize() const
{
return base::estimatedSize();
return base::estimatedSize() + alternates.capacity();
}

HouseDesc::HouseDesc( u32 objtype, Clib::ConfigElem& elem, const Plib::Package* pkg )
Expand Down
2 changes: 2 additions & 0 deletions pol-core/pol/item/itemdesc.h
Expand Up @@ -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<u16> alternates;
};

class HouseDesc final : public MultiDesc
Expand Down
6 changes: 2 additions & 4 deletions pol-core/pol/module/boatmod.cpp
Expand Up @@ -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<Core::UFACING>( direction & 7 );
boat->move( move_dir, static_cast<u8>( speed ), false );
return new Bscript::BLong( 1 );
return new Bscript::BLong( boat->move( move_dir, static_cast<u8>( speed ), false ) );
}
return nullptr;
}
Expand Down Expand Up @@ -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<Core::UFACING>( direction & 7 );
boat->move( move_dir, static_cast<u8>( speed ), true );
return new Bscript::BLong( 1 );
return new Bscript::BLong( boat->move( move_dir, static_cast<u8>( speed ), true ) );
}
return nullptr;
}
Expand Down
10 changes: 9 additions & 1 deletion pol-core/pol/multi/boat.cpp
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions pol-core/pol/uoscrobj.cpp
Expand Up @@ -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<const Items::BoatDesc&>( itemdesc() );
if ( index < 0 || static_cast<size_t>( 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;
}
Expand Down
127 changes: 65 additions & 62 deletions pol-core/poltool/testfiles.cpp
Expand Up @@ -540,68 +540,71 @@ void FileGenerator::modifyMultis( std::vector<std::vector<T>>& multis )
return e;
};
multis.resize( 0x3fff, std::vector<T>() );
// first boat
multis[0x0] = std::vector<T>{
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<T>{
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<T>{
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<T>{
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<T>{
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<T>{
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<T>{
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<T>{
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<T>{
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 ),
Expand Down