给对象添加重量

游戏中你可以接触到的所有物品通常都有一定的重量。重量的作用因游戏而异。通常,它限制你能携带多少东西。如果一块重石头掉在你身上,可能会比气球更疼。如果你想要更复杂的效果,压力板可能只有在踩上去的东西足够重时才会触发。

# 在 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):
    # ...
  • 第6行:我们使用 ObjectParent 混入类。由于此混入类用于 CharactersExitsRooms 以及 Object,这意味着所有这些都会自动拥有重量!

  • 第8行:我们使用 AttributeProperty 来设置“默认”重量为1(无论那是什么)。设置 autocreate=False 意味着在重量实际从默认的1更改之前,不会创建任何实际的 Attribute。请参阅 AttributeProperty 文档以了解其注意事项。

  • 第10和11行:在 total_weight 上使用 @property 装饰器意味着我们以后可以调用 obj.total_weight 而不是 obj.total_weight()

  • 第12行:我们通过遍历 self.contents 来汇总所有“在”此对象中的物品的重量。由于现在 所有 对象都有重量,这应该始终有效!

让我们检查一下几个可靠的箱子的重量:

> create/drop box1
> py self.search("box1").weight
1 
> py self.search("box1").total_weight
1 

让我们把另一个箱子放到第一个箱子里。

> 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

限制携带的重量

要限制你能携带的重量,你首先需要知道自己的力量。

# 在 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

在这里,我们确保添加另一个 AttributeProperty 来告诉我们能携带多少。在实际游戏中,这可能基于角色的力量。当我们考虑已经携带的重量时,不应包括 我们自己的 重量,所以我们减去它。

为了遵守这个限制,我们需要重写默认的 get 命令。

# 在 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()

在这里,我们为尝试拾取的物品的重量添加了额外的检查,然后使用 super().func() 调用正常的 CmdGet