Skip to content

Commit

Permalink
Add held_weight_multiplier for containers; Fix missing tooltip upda…
Browse files Browse the repository at this point in the history
…tes (for weight) (#646)

* Implementation

* wip testing

* allow setting held weight mod to long value

* more tests

* address github actions warnings
- unary minus operator applied to unsigned type, result still unsigned

* Add docs, core-changes

* fix GetItemDescriptor() for HeldWeightMultiplierMod; update tests

* update docs a bit more

* Remove mod suffix
  • Loading branch information
KevinEady committed May 14, 2024
1 parent 9d2bf0e commit c4f6e32
Show file tree
Hide file tree
Showing 18 changed files with 487 additions and 19 deletions.
3 changes: 3 additions & 0 deletions docs/docs.polserver.com/pol100/configfiles.xml
Expand Up @@ -1569,6 +1569,9 @@ Container (objtype)
[MaxWeight (int weight {default to servspecopt.cfg})]
[MaxItems (int number {default to servspecopt.cfg})]
[MaxSlots (int 1-255 {default to servspecopt.cfg})]

[HeldWeightMultiplier (double {default 1.0})]

[NoDropException (0/1 {default 0})]
[CanInsertScript (string scriptname)]
[OnInsertScript (string scriptname)]
Expand Down
13 changes: 12 additions & 1 deletion docs/docs.polserver.com/pol100/corechanges.xml
Expand Up @@ -2,9 +2,20 @@
<ESCRIPT>
<header>
<topic>Latest Core Changes</topic>
<datemodified>04-14-2024</datemodified>
<datemodified>05-13-2024</datemodified>
</header>
<version name="POL100.2.0">
<entry>
<date>05-13-2024</date>
<author>Kevin:</author>
<change type="Added">container.held_weight_multiplier, item descriptor HeldWeightMultiplier to dynamically<br/>
modify a container's held weight. For example, on a backpack (having weight 3 stones) that<br/>
contains items totalling a weight of 100 stone, setting this property to 0.5 would have the<br/>
backpack weigh 53 (3 + 100 * 0.5) stone. Similarly, setting this property to 2 would have<br/>
the backpack weigh 203 stone.</change>
<change type="Fixed">Tooltip updates to client are now correctly triggered for some previously missing scenarios<br/>
(eg. dragging an item from a container).</change>
</entry>
<entry>
<date>04-24-2024</date>
<author>Reloecc:</author>
Expand Down
1 change: 1 addition & 0 deletions docs/docs.polserver.com/pol100/objref.xml
Expand Up @@ -501,6 +501,7 @@
<member mname="max_items_mod" type="Integer" access="r/w" mdesc="from -32768 to 32767, modifier for max items allowed in the container" />
<member mname="max_weight_mod" type="Integer" access="r/w" mdesc="from -32768 to 32767, modifier for max weight allowed in the container" />
<member mname="max_slots_mod" type="Integer" access="r/w" mdesc="from -32768 to 32767, modifier for max slots allowed in the container" />
<member mname="held_weight_multiplier" type="Double" access="r/w" mdesc="Multiplicative modifier when calculating the container's held weight. For example, on an backpack (having weight 3 stones) that contains items totalling a weight of 100 stone, setting this property to 0.5 would have the backpack weigh 53 (3 + 100 * 0.5) stone." />
<member mname="no_drop_exception" type="Boolean" access="r/w" mdesc="defines if npc is a valid target even if no_drop is set for the item" />
</class>

Expand Down
1 change: 1 addition & 0 deletions pol-core/bscript/objaccess.cpp
Expand Up @@ -275,6 +275,7 @@ ObjMember object_members[] = {
{ MBR_PILOT, "pilot", false },
{ MBR_BUFFS, "buffs", false },
{ MBR_WEIGHT_MULTIPLIER_MOD, "weight_multiplier_mod", false },
{ MBR_HELD_WEIGHT_MULTIPLIER, "held_weight_multiplier", false },
};
int n_objmembers = sizeof object_members / sizeof object_members[0];
ObjMember* getKnownObjMember( const char* token )
Expand Down
1 change: 1 addition & 0 deletions pol-core/bscript/objmembers.h
Expand Up @@ -300,6 +300,7 @@ enum MemberID
MBR_PILOT,
MBR_BUFFS,
MBR_WEIGHT_MULTIPLIER_MOD,
MBR_HELD_WEIGHT_MULTIPLIER, // 260
};

inline auto format_as( MemberID id )
Expand Down
8 changes: 8 additions & 0 deletions pol-core/doc/core-changes.txt
@@ -1,4 +1,12 @@
-- POL100.2.0 --
05-13-2024 Kevin:
Added: container.held_weight_multiplier, item descriptor HeldWeightMultiplier to dynamically
modify a container's held weight. For example, on a backpack (having weight 3 stones) that
contains items totalling a weight of 100 stone, setting this property to 0.5 would have the
backpack weigh 53 (3 + 100 * 0.5) stone. Similarly, setting this property to 2 would have
the backpack weigh 203 stone.
Fixed: Tooltip updates to client are now correctly triggered for some previously missing scenarios
(eg. dragging an item from a container).
04-24-2024 Reloecc:
Added: `NpcMinimumMovementDelay` parameter to `servspecopt.cfg`. It controls maximum movement speed of NPCs.
04-14-2024 Kevin:
Expand Down
24 changes: 17 additions & 7 deletions pol-core/pol/containr.cpp
Expand Up @@ -62,6 +62,7 @@ UContainer::UContainer( const Items::ContainerDesc& id )
held_item_count_( 0 )
{
no_drop_exception( id.no_drop_exception );
held_weight_multiplier( id.held_weight_multiplier );
}

UContainer::~UContainer()
Expand Down Expand Up @@ -143,17 +144,21 @@ bool UContainer::can_add_bulk( int tli_diff, int item_count_diff, int weight_dif
if ( contents_.size() + tli_diff >= MAX_CONTAINER_ITEMS )
return false;

if ( weight() + weight_diff > USHRT_MAX /* gcc...std::numeric_limits<unsigned short>::max()*/ )
if ( weight() + weight_diff * held_weight_multiplier() > USHRT_MAX )
return false;

if ( held_weight_ + weight_diff > max_weight() )
if ( ( held_weight_ + weight_diff ) * held_weight_multiplier() > max_weight() )
return false;

if ( held_item_count_ + item_count_diff > max_items() )
return false;

if ( container != nullptr )
return container->can_add_bulk( 0, 0, weight_diff );
{
int modded_diff = ( ( held_weight_ + weight_diff ) * held_weight_multiplier() ) -
( held_weight_ * held_weight_multiplier() );
return container->can_add_bulk( 0, 0, modded_diff );
}
else
return true;
}
Expand Down Expand Up @@ -228,19 +233,19 @@ void UContainer::add_bulk( int item_count_delta, int weight_delta )
// passert( !stateManager.gflag_enforce_container_limits || (held_weight_ + weight_delta <=
// MAX_WEIGHT) );

if ( container != nullptr )
container->add_bulk( 0, -static_cast<int>( weight() ) );
int newweight = held_weight_;
newweight += weight_delta;
held_weight_ = Clib::clamp_convert<u16>( newweight );
if ( container != nullptr )
{
container->add_bulk( 0, weight_delta );
}
container->add_bulk( 0, weight() );
}


unsigned int UContainer::weight() const
{
return Items::Item::weight() + held_weight_;
return Items::Item::weight() + held_weight_ * held_weight_multiplier();
}

unsigned int UContainer::item_count() const
Expand Down Expand Up @@ -880,6 +885,8 @@ void UContainer::printProperties( Clib::StreamWriter& sw ) const
sw.add( "Max_Slots_mod", max_slots_mod() );
if ( no_drop_exception() != default_no_drop_exception() )
sw.add( "NoDropException", no_drop_exception() );
if ( has_held_weight_multiplier() )
sw.add( "HeldWeightMultiplier", held_weight_multiplier() );
}

void UContainer::readProperties( Clib::ConfigElem& elem )
Expand All @@ -889,6 +896,8 @@ void UContainer::readProperties( Clib::ConfigElem& elem )
max_weight_mod( static_cast<s16>( elem.remove_int( "MAX_WEIGHT_MOD", 0 ) ) );
max_slots_mod( static_cast<s8>( elem.remove_int( "MAX_SLOTS_MOD", 0 ) ) );
no_drop_exception( elem.remove_bool( "NoDropException", default_no_drop_exception() ) );
held_weight_multiplier(
elem.remove_double( "HeldWeightMultiplier", desc.held_weight_multiplier ) );
}

unsigned int UContainer::find_sumof_objtype_noninuse( u32 objtype, u32 amtToGet,
Expand Down Expand Up @@ -931,6 +940,7 @@ Items::Item* UContainer::clone() const
item->max_weight_mod( this->max_weight_mod() );
item->max_slots_mod( this->max_slots_mod() );
item->no_drop_exception( no_drop_exception() );
item->held_weight_multiplier( held_weight_multiplier() );

return item;
}
Expand Down
3 changes: 3 additions & 0 deletions pol-core/pol/containr.h
Expand Up @@ -175,6 +175,8 @@ class UContainer : public ULockable
virtual Bscript::BObjectImp* set_script_member( const char* membername, int value ) override;
virtual Bscript::BObjectImp* set_script_member_id( const int id,
int value ) override; // id test
virtual Bscript::BObjectImp* set_script_member_id_double( const int id, double value ) override;

virtual bool get_method_hook( const char* methodname, Bscript::Executor* ex, ExportScript** hook,
unsigned int* PC ) const override;

Expand Down Expand Up @@ -214,6 +216,7 @@ class UContainer : public ULockable
DYN_PROPERTY( max_items_mod, s16, Core::PROP_MAX_ITEMS_MOD, 0 );
DYN_PROPERTY( max_slots_mod, s8, Core::PROP_MAX_SLOTS_MOD, 0 );
DYN_PROPERTY( max_weight_mod, s16, Core::PROP_MAX_WEIGHT_MOD, 0 );
DYN_PROPERTY( held_weight_multiplier, double, Core::PROP_HELD_WEIGHT_MULTIPLIER, 1.0 );

bool no_drop_exception() const;
void no_drop_exception( bool newvalue );
Expand Down
4 changes: 3 additions & 1 deletion pol-core/pol/dropitem.cpp
Expand Up @@ -125,6 +125,8 @@ bool place_item_in_container( Network::Client* client, Items::Item* item, UConta
cont->on_insert_add_item( client->chr, UContainer::MT_PLAYER, item );
}

item->increv_send_object_recursive();

client->restart();
return true;
}
Expand Down Expand Up @@ -722,7 +724,7 @@ bool drop_item_on_object( Network::Client* client, Items::Item* item, u32 target
return true;
u16 amtadded = item->getamount();
exitem->add_to_self( item );
update_item_to_inrange( exitem );
exitem->increv_send_object_recursive();

cont->on_insert_increase_stack( client->chr, UContainer::MT_PLAYER, exitem, amtadded );

Expand Down
1 change: 1 addition & 0 deletions pol-core/pol/dynproperties.h
Expand Up @@ -178,6 +178,7 @@ enum DynPropTypes : u8
PROP_ORIG_SWING_SPEED_INCREASE = 91, // Npc
PROP_PARRYCHANCE_MOD = 92, // Character
PROP_WEIGHT_MULTIPLIER_MOD = 93, // Item
PROP_HELD_WEIGHT_MULTIPLIER = 94, // Container

PROP_FLAG_SIZE // used for bitset size
};
Expand Down
5 changes: 5 additions & 0 deletions pol-core/pol/getitem.cpp
Expand Up @@ -222,6 +222,11 @@ void GottenItem::handle( Network::Client* client, PKTIN_07* msg )
item->set_decay_after( 60 );
}

if ( orig_container )
{
orig_container->increv_send_object_recursive();
}

// FIXME : Are these all the possibilities for sources and updating, correctly?
if ( gotten_info._source == GOTTEN_ITEM_TYPE::GOTTEN_ITEM_ON_GROUND )
{
Expand Down
11 changes: 11 additions & 0 deletions pol-core/pol/item/item.cpp
Expand Up @@ -750,6 +750,17 @@ void Item::add_to_self( Item*& item )
item = nullptr;
}

void Item::increv_send_object_recursive()
{
auto item = this;
do
{
item->increv();
send_object_cache_to_inrange( item );
item = item->container;
} while ( item != nullptr );
}

#ifdef PERGON
// Pergon: Re-Calculate Property CreateTime after Merging of two Stacks
void Item::ct_merge_stacks_pergon( Item*& item_sub )
Expand Down
2 changes: 2 additions & 0 deletions pol-core/pol/item/item.h
Expand Up @@ -179,6 +179,8 @@ class Item : public Core::UObject
bool has_only_default_cprops( const ItemDesc* compare = nullptr ) const;
void add_to_self( Item*& item ); // deletes the item passed

void increv_send_object_recursive();

#ifdef PERGON
void ct_merge_stacks_pergon(
Item*& item_sub ); // Pergon: Re-Calculate Property CreateTime after Merging of two Stacks
Expand Down
3 changes: 3 additions & 0 deletions pol-core/pol/item/itemdesc.cpp
Expand Up @@ -932,6 +932,7 @@ ContainerDesc::ContainerDesc( u32 objtype, Clib::ConfigElem& elem, const Plib::P
Core::settingsManager.ssopt.default_container_max_items ) ),
max_slots( static_cast<u8>(
elem.remove_ushort( "MAXSLOTS", Core::settingsManager.ssopt.default_max_slots ) ) ),
held_weight_multiplier( elem.remove_double( "HeldWeightMultiplier", 1.0 ) ),
no_drop_exception( elem.remove_bool( "NoDropException", false ) ),
can_insert_script( elem.remove_string( "CANINSERTSCRIPT", "" ), pkg, "scripts/control/" ),
on_insert_script( elem.remove_string( "ONINSERTSCRIPT", "" ), pkg, "scripts/control/" ),
Expand Down Expand Up @@ -961,6 +962,7 @@ void ContainerDesc::PopulateStruct( Bscript::BStruct* descriptor ) const
descriptor->addMember( "MaxWeight", new BLong( max_weight ) );
descriptor->addMember( "MaxItems", new BLong( max_items ) );
descriptor->addMember( "MaxSlots", new BLong( max_slots ) );
descriptor->addMember( "HeldWeightMultiplier", new Double( held_weight_multiplier ) );
descriptor->addMember( "NoDropException", new BLong( no_drop_exception ) );
descriptor->addMember( "CanInsertScript", new String( can_insert_script.relativename( pkg ) ) );
descriptor->addMember( "CanRemoveScript", new String( can_remove_script.relativename( pkg ) ) );
Expand All @@ -976,6 +978,7 @@ size_t ContainerDesc::estimatedSize() const
+ sizeof( u16 ) /*max_items*/
+ sizeof( u8 ) /*max_slots*/
+ sizeof( bool ) /*no_drop_exception*/
+ sizeof( double ) /*held_weight_multiplier*/
+ can_insert_script.estimatedSize() + on_insert_script.estimatedSize() +
can_remove_script.estimatedSize() + on_remove_script.estimatedSize();
}
Expand Down
1 change: 1 addition & 0 deletions pol-core/pol/item/itemdesc.h
Expand Up @@ -198,6 +198,7 @@ class ContainerDesc : public ItemDesc
u16 max_items;

u8 max_slots;
double held_weight_multiplier;

bool no_drop_exception;

Expand Down
50 changes: 40 additions & 10 deletions pol-core/pol/uoscrobj.cpp
Expand Up @@ -1620,16 +1620,7 @@ BObjectImp* Item::set_script_member_id_double( const int id, double value )
weight_multiplier_mod( value );
}

increv();
send_object_cache_to_inrange( this );

auto cont = container;
while ( cont )
{
cont->increv();
send_object_cache_to_inrange( cont );
cont = cont->container;
}
increv_send_object_recursive();

UpdateCharacterWeight( this );
return new Double( weight_multiplier_mod() );
Expand Down Expand Up @@ -3788,6 +3779,8 @@ BObjectImp* UContainer::get_script_member_id( const int id ) const
break;
case MBR_NO_DROP_EXCEPTION:
return new BLong( no_drop_exception() );
case MBR_HELD_WEIGHT_MULTIPLIER:
return new Double( held_weight_multiplier() );
default:
return nullptr;
}
Expand Down Expand Up @@ -3820,6 +3813,43 @@ BObjectImp* UContainer::set_script_member_id( const int id, int value )
case MBR_NO_DROP_EXCEPTION:
no_drop_exception( value ? true : false );
return new BLong( no_drop_exception() );
case MBR_WEIGHT_MULTIPLIER_MOD:
return set_script_member_id_double( id, value );
case MBR_HELD_WEIGHT_MULTIPLIER:
return set_script_member_id_double( id, value );
default:
return nullptr;
}
return new BLong( value );
}

Bscript::BObjectImp* UContainer::set_script_member_id_double( const int id, double value )
{
BObjectImp* imp = base::set_script_member_id_double( id, value );
if ( imp != nullptr )
return imp;

switch ( id )
{
case MBR_HELD_WEIGHT_MULTIPLIER:
{
if ( container )
{
container->add_bulk( 0, -static_cast<int>( weight() ) );
held_weight_multiplier( value );
container->add_bulk( 0, weight() );
}
else
{
held_weight_multiplier( value );
}

increv_send_object_recursive();

UpdateCharacterWeight( this );

return new Double( held_weight_multiplier() );
}
default:
return nullptr;
}
Expand Down
43 changes: 43 additions & 0 deletions testsuite/pol/testpkgs/item/itemdesc.cfg
Expand Up @@ -64,3 +64,46 @@ Item 0x400003
Graphic 0x1
ControlScript control_destroy
}

Container 0x200010
{
Name heldweightmultipliermod_half
Graphic 0xe75
Gump 0x3C
MinX 44
MaxX 143
MinY 65
MaxY 140
Weight 50
MaxWeight 100
HeldWeightMultiplier 0.5
}

Container 0x200011
{
Name heldweightmultipliermod_quarter
Graphic 0xe75
Gump 0x3C
MinX 44
MaxX 143
MinY 65
MaxY 140
Weight 50
MaxWeight 100
HeldWeightMultiplier 0.25
}

Item 0x200012
{
Name goldcoin_heavy
Graphic 0xeed
Weight 1
}

Item 0x200013
{
Name goldcoin_heavy2
Graphic 0xeed
Color 2
Weight 1
}

0 comments on commit c4f6e32

Please sign in to comment.