Give objects weight¶
All in-game objets you can touch usually has some weight. What weight does varies from game to game. Commonly it limits how much you can carry. A heavy stone may also hurt you more than a ballon, if it falls on you. If you want to get fancy, a pressure plate may only trigger if the one stepping on it is heavy enough.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # inside your mygame/typeclasses/objects.py from evennia import DefaultObject from evennia import AttributeProperty class ObjectParent: weight = AttributeProperty(default=1, autocreate=False) @property def total_weight(self): return self.weight + sum(obj.total_weight for obj in self.contents) class Object(ObjectParent, DefaultObject): # ... |
Line 6: We use the
ObjectParent
mixin. Since this mixin is used forCharacters
,Exits
andRooms
as well as forObject
, it means all of those will automatically also have weight!Line 8: We use an AttributeProperty to set up the ‘default’ weight of 1 (whatever that is). Setting
autocreate=False
means no actualAttribute
will be created until the weight is actually changed from the default of 1. See theAttributeProperty
documentation for caveats with this.Line 10 and 11: Using the
@property
decorator ontotal_weight
means that we will be able to callobj.total_weight
instead ofobj.total_weight()
later.Line 12: We sum up all weights from everything “in” this object, by looping over
self.contents
. Since all objects will have weight now, this should always work!
Let’s check out the weight of some trusty boxes
> create/drop box1
> py self.search("box1").weight
1
> py self.search("box1").total_weight
1
Let’s put another box into the first one.
> create/drop box2
> py self.search("box2").total_weight
1
> py self.search("box2").location = self.search("box1")
> py self.search(box1).total_weight
2
Limit inventory by weight carried¶
To limit how much you can carry, you first need to know your own strength
# in mygame/typeclasses/characters.py
from evennia import AttributeProperty
# ...
class Character(ObjectParent, DefaultCharacter):
carrying_capacity = AttributeProperty(10, autocreate=False)
@property
def carried_weight(self):
return self.total_weight - self.weight
Here we make sure to add another AttributeProperty
telling us how much to carry. In a real game, this may be based on how strong the Character is. When we consider how much weight we already carry, we should not include our own weight, so we subtract that.
To honor this limit, we’ll need to override the default get
command.
# in mygame/commands/command.py
# ...
from evennia import default_cmds
# ...
class WeightAwareCmdGet(default_cmds.CmdGet):
def func(self):
caller = self.caller
if not self.args:
caller.msg("Get what?")
return
obj = caller.search(self.args)
if (obj.weight + caller.carried_weight
> caller.carrying_capacity):
caller.msg("You can't carry that much!")
return
super().func()
Here we add an extra check for the weight of the thing we are trying to pick up, then we call the normal CmdGet
with super().func()
.