notes on the patch i just posted (ctf-flag.patch.txt)
Modifications to support items that can affect users on equp/unequip
Overview
- wanted way for items to update character, for example changing
their outfit detail as a result of picking up
I spent a lot of time trying to identify a single, symmetric (both
equip and unequip) set of interfaces. Player/RPEntity.equip, or maybe
RPEntity.equipIt, sounded like good candidates, but not all equip
paths go through there. After a lot of tracing, and several
experiments, I think that focusing on the item is the simplest thing
to do in the current code base - a new Item subclass that specially
handles removeFromWorld, and a slight modification to
DestinationObject.addToWorld, to make sure that the special items know
when they are equpped by a player, and where.
Testing the changes:
After applying the patch, restart server, and
/summon flag
drag the "flag" (currently a teddy bear icon) on to either hand, and
off again. player outfit should get a balloon detail, and then
back to normal
I'm not sure yet how to develop a useful unit test for this
functionality. It would have to cover many paths - EquipActions,
DropActions, direct adds, ...
subclass of EntityUpdatingItem that updates player's outfit when
flag is picked up and dropped
data/conf/items/capturetheflag.xml
currently just a teddy bear image
<item name="flag">
<type class="misc" subclass="teddy" tileid="-1"/>
<description>You see a flag. Its soft and cuddly, and children love them.</description>
.addToWorld updated to call item.onEquipped(player slot), if the
item is subclass of EntityUpdatingItem.
TODO: could make the item interface "symmetric" by adding
EntityUpdatingItem.addToWorld
the changes to DestinationObject for making sure item.onEquipped is
called correctly, and EntityUpdatingItem.removeFromWorld, to make
sure item.onUnequipped is called correctly, cover all drags (bag to
body (EquipAction), body to body (EquipAction), body to ground
(DropAction).
data/conf/items/items.xml
just include the new items/capturetheflag.xml file
Notes:
- i think this could be used to call updateItemAtkDef less often
- apparently currently called constantly (when food moved in bag, ...)
- i think this could be foundation for other ideas
- magic rings, ...
Limitations:
- does not yet drop flag when teleport, die, quit
- does not work correctly if you summon straight in to hand,
or player could buy straight to an empty hand
- different code paths, do not yet call Item.onEquipped (or
Item.addToWorld)
- experiments that i threw out:
- player-centric:
- player.equipped(Entity item, String slot)/player.unequipped
- EntityUpdatingitem.onEquipped/onUnequpped is simpler, and kind of makes sense
- it's the object modifying the user, ...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
notes on the patch i just posted (ctf-flag.patch.txt)
Modifications to support items that can affect users on equp/unequip
Overview
- wanted way for items to update character, for example changing
their outfit detail as a result of picking up
I spent a lot of time trying to identify a single, symmetric (both
equip and unequip) set of interfaces. Player/RPEntity.equip, or maybe
RPEntity.equipIt, sounded like good candidates, but not all equip
paths go through there. After a lot of tracing, and several
experiments, I think that focusing on the item is the simplest thing
to do in the current code base - a new Item subclass that specially
handles removeFromWorld, and a slight modification to
DestinationObject.addToWorld, to make sure that the special items know
when they are equpped by a player, and where.
Testing the changes:
After applying the patch, restart server, and
/summon flag
drag the "flag" (currently a teddy bear icon) on to either hand, and
off again. player outfit should get a balloon detail, and then
back to normal
I'm not sure yet how to develop a useful unit test for this
functionality. It would have to cover many paths - EquipActions,
DropActions, direct adds, ...
Modifications
New Files:
games.stendhal.server.entity.item.EntityUpdatingItem.java
base class for onEquipped(Entity, slot) and onUnequipped(Entity, slot)
these methods give the special item a chance to manipulate the
entity.
overrides removeFromWorld, which is the primary mechanism for
Actions to transfer items from one entity to another.
games.stendhal.server.entity.item.CaptureTheFlagFlag.java
subclass of EntityUpdatingItem that updates player's outfit when
flag is picked up and dropped
data/conf/items/capturetheflag.xml
currently just a teddy bear image
<item name="flag">
<type class="misc" subclass="teddy" tileid="-1"/>
<description>You see a flag. Its soft and cuddly, and children love them.</description>
<implementation class-name="games.stendhal.server.entity.item.CaptureTheFlagFlag"/>
<attributes>
</attributes>
<weight value="1.0"/>
<value value="1"/>
<equipable>
<slot name="rhand"/>
<slot name="lhand"/>
<slot name="ground"/>
<!-- i think that hand-only is a good policy -->
<!-- <slot name="content"/> -->
<!-- <slot name="bag"/> -->
</equipable>
</item>
Changes
games.stendhal.server.actions.equip.DestinationObject.java
.addToWorld updated to call item.onEquipped(player slot), if the
item is subclass of EntityUpdatingItem.
TODO: could make the item interface "symmetric" by adding
EntityUpdatingItem.addToWorld
the changes to DestinationObject for making sure item.onEquipped is
called correctly, and EntityUpdatingItem.removeFromWorld, to make
sure item.onUnequipped is called correctly, cover all drags (bag to
body (EquipAction), body to body (EquipAction), body to ground
(DropAction).
data/conf/items/items.xml
just include the new items/capturetheflag.xml file
Notes:
- i think this could be used to call updateItemAtkDef less often
- apparently currently called constantly (when food moved in bag, ...)
- i think this could be foundation for other ideas
- magic rings, ...
Limitations:
- does not yet drop flag when teleport, die, quit
- does not work correctly if you summon straight in to hand,
or player could buy straight to an empty hand
- different code paths, do not yet call Item.onEquipped (or
Item.addToWorld)
- experiments that i threw out:
- player-centric:
- player.equipped(Entity item, String slot)/player.unequipped
- EntityUpdatingitem.onEquipped/onUnequpped is simpler, and kind of makes sense
- it's the object modifying the user, ...
updates to support shooting special arrows at a flag carrier, to try to make carrier drop flag