Python mud equip command

411 Views Asked by At

I am trying to make a mud but when making a equip command I ran into this error.

    if item.types == "weapon":
AttributeError: 'unicode' object has no attribute 'types'

I would like to fix my code so that it allows users to type equip sword and it will search for that item in his/her inventory and apply the stats.

Here is my item code

#weapons

class Weapon():
    def __init__(self, name, ATK, gold, types):
        self.name = name
        self.ATK = ATK
        self.gold = gold
        self.types = types


club = Weapon("club", 1, 3, "weapon")
sword = Weapon("sword", 3, 10,"weapon")
axe = Weapon("axe", 4, 15,"weapon")
bow = Weapon("Hailey's bow", 10, 40,"weapon")
swordX = Weapon("Gods Sword", 8000, 8000,"weapon")

and here is my player code

players[id] = { 
            "name": None,
            "room": "Tavern",
            "ATK": 5,
            "hp": 20,
            "inventory": {},
            "armorName": None,
            "armorPT": None,
            "weaponName": None,
            "weaponPT": None,
        }

and last my equip command code

elif command == "equip":
            x = params.lower()
            rm = rooms[players[id]["room"]]
            if x in players[id]["inventory"]:
                item = players[id]["inventory"][x]
                weapon = players[id]["weaponName"]
                wStat = players[id]["weaponPT"]
                armor = players[id]["armorName"]
                aStat = players[id]["armorPT"]
                hp = players[id]["hp"]
                ATK = players[id]["ATK"]
                if item.types == "weapon":
                    weapon = item.name
                    wStat = item.ATK
                    ATK += wStat
                    mud.send_message(id,"you equip %s" % weapon)
                    mud.send_message(id,"NEW ATK: %d" % ATK)
                elif item.type == "armor":
                    armor = item.name
                    aStat = item.DEF
                    hp += aStat
                    mud.send_message(id,"you equip %s" % armor)
                    mud.send_message(id,"NEW DEF: %d" % hp)

                else:
                    mud.send_message(id,"not a vaid item type")

            else:
                mud.send_message(id,"you dont have this item")

If you think I need to add any more code for it to make sense, please tell me.

EDIT: i think i found where the problem is but i don't know how to fix it i believe it is in the take command and hoe it is added to the inventory it is being added as a string i don't know how to fix this

here is the code

elif command == "take":
            x = params.lower()
            rm = rooms[players[id]["room"]]

            if rm["item"] == "yes":
                if x in rm["itemName"]:
                    players[id]["inventory"][x] = x
                    del rm["itemName"][x]
                    mud.send_message(id, "you picked up %s" % x)
                    print players[id]["inventory"][x]

                else:
                    mud.send_message(id,"You dont see that item")
            else:
                mud.send_message(id,"there is no item here")
2

There are 2 best solutions below

0
On BEST ANSWER

The error message tells that item is a unicode string, and not an instance of the class Weapon.

Therefore, when you try to access item.types you get an error.

N.B. not also that the next condition should be elif item.types == "armor": (missing s).

4
On

One of the "bad smells" in OO programming is checking the type of an object yourself. If you're checking the type, there's a good chance you should change how you implement your design.

In this case, I'd like to suggest that you create Player methods called equip(self, obj), set_weapon(self, obj), set_armor(self, obj), and create various object methods called equip_on(self, Player) and unequip_on(self, Player).

Then you can divide up authority and responsibility based on class and type and which objects knows which things:

  • Player.equip could deal with weight limits and taking an object from the room that contained it.
  • Weapon.equip_on would know that it's a weapon, and call the appropriate method on Player.
  • Player.set_weapon would know it must first un-equip an existing weapon.
  • Weapon.unequip_on could refuse to be unequipped if it were cursed.

If you implement your methods correctly, each one of them will seem simple and straightforward, but they will add a little more information to the picture each time. This double dispatch is a fast, easy way to deal with type information without having to sprinkle if type(obj) == statements throughout your code.