diff --git a/asciifarm/client/inputhandler.py b/asciifarm/client/inputhandler.py index 0657749..4281c01 100644 --- a/asciifarm/client/inputhandler.py +++ b/asciifarm/client/inputhandler.py @@ -87,7 +87,7 @@ class InputHandler: elif key == "^I": # tab # return to game but keep entered string self.typing = False - elif key.isprintable(): + elif key.isprintable() and len(key) == 1: self.string = self.string[:self.cursor] + key + self.string[self.cursor:] self.cursor += len(key) diff --git a/asciifarm/server/components/__init__.py b/asciifarm/server/components/__init__.py index 5644a37..da28bb8 100644 --- a/asciifarm/server/components/__init__.py +++ b/asciifarm/server/components/__init__.py @@ -1,7 +1,5 @@ from .build import Build -from .equippable import Equippable -from .food import Food from .item import Item from .optionmenu import OptionMenu from .select import Select diff --git a/asciifarm/server/components/equippable.py b/asciifarm/server/components/equippable.py deleted file mode 100644 index c49bb6f..0000000 --- a/asciifarm/server/components/equippable.py +++ /dev/null @@ -1,45 +0,0 @@ - -from .component import Component -from ..datacomponents import Equipment - -class Equippable(Component): - """ item type for item that can be equipped""" - - def __init__(self, slot, stats=None): - if stats is None: - stats = {} - self.slot = slot - self.stats = stats - - def attach(self, obj): - self.owner = obj - obj.addListener("roomjoin", self.roomJoin) - - def roomJoin(self, o, roomData, stamp): - self.roomData = roomData - - def getSlot(self): - return self.slot - - def use(self, user): - equipment = self.roomData.getComponent(user, Equipment) - if self.slot in equipment.slots and equipment.slots[self.slot] is None: - # Later it should be able to replace whatever is in the slot, but I don't want to deal with that now - # therefore, it can currently only be placed in empty slots - equipment[self.slot] = self.owner - #self.equipped = True - #equipment = user.getComponent("equipment") - #if equipment.canEquip(self): - #equipment.equip(self.slot, self.owner) - self.owner.trigger("drop") - - def getStat(self, stat): - return self.stats.get(stat, 0) - - def toJSON(self): - return { - "slot": self.slot, - "stats": self.stats - } - - diff --git a/asciifarm/server/components/food.py b/asciifarm/server/components/food.py deleted file mode 100644 index 50ec44b..0000000 --- a/asciifarm/server/components/food.py +++ /dev/null @@ -1,22 +0,0 @@ - -from .component import Component - - -class Food(Component): - - - def __init__(self, health): - self.healing = health - - def attach(self, obj): - self.owner = obj - - - def use(self, user): - fighter = user.getComponent("fighter") - if fighter: - fighter.heal(self.healing, self.owner) - self.owner.trigger("drop") - - def toJSON(self): - return {"health": self.healing} diff --git a/asciifarm/server/datacomponents/__init__.py b/asciifarm/server/datacomponents/__init__.py index 943a9c1..15ba31a 100644 --- a/asciifarm/server/datacomponents/__init__.py +++ b/asciifarm/server/datacomponents/__init__.py @@ -17,9 +17,9 @@ from .periodic import Periodic from .equipment import Equipment from .spawner import Spawner from .item import Item -from .held import Held +from .equippable import Equippable -from .messages import Message, EnterMessage, LootMessage, StartTimer, Create, SpawnMessage, EatMessage +from .messages import Message, EnterMessage, LootMessage, StartTimer, Create, SpawnMessage, UseMessage class Remove: pass @@ -39,3 +39,7 @@ class Trap: class Home: def __init__(self, home): self.home = home + +class Food: + def __init__(self, healing): + self.healing = healing diff --git a/asciifarm/server/datacomponents/equippable.py b/asciifarm/server/datacomponents/equippable.py new file mode 100644 index 0000000..9df5e68 --- /dev/null +++ b/asciifarm/server/datacomponents/equippable.py @@ -0,0 +1,6 @@ + +class Equippable: + + def __init__(self, slot, stats): + self.slot = slot + self.stats = stats diff --git a/asciifarm/server/datacomponents/held.py b/asciifarm/server/datacomponents/held.py deleted file mode 100644 index 3606776..0000000 --- a/asciifarm/server/datacomponents/held.py +++ /dev/null @@ -1,6 +0,0 @@ - - -class Held: - - def __init__(self, holder): - self.holder = holder diff --git a/asciifarm/server/datacomponents/messages.py b/asciifarm/server/datacomponents/messages.py index ad675ee..6927a43 100644 --- a/asciifarm/server/datacomponents/messages.py +++ b/asciifarm/server/datacomponents/messages.py @@ -26,3 +26,7 @@ class SpawnMessage(Message): class EatMessage(Message): pass + +class UseMessage(Message): + def __init__(self, actor): + self.actor = actor diff --git a/asciifarm/server/gameobjects/crops.py b/asciifarm/server/gameobjects/crops.py index 72246a8..7a65422 100644 --- a/asciifarm/server/gameobjects/crops.py +++ b/asciifarm/server/gameobjects/crops.py @@ -1,8 +1,8 @@ from ..entity import Entity -from ..components import Build, Food -from ..datacomponents import Interact, Loot, Remove, Serialise, Static, LootMessage, Periodic, StartTimer, Create, Item +from ..components import Build +from ..datacomponents import Interact, Loot, Remove, Serialise, Static, LootMessage, Periodic, StartTimer, Create, Item, Food from ..template import Template entities = {} @@ -92,7 +92,7 @@ createCrop("carrot", [ Stage("carrotplant", sprite="smallplant", height=0.5, harvest=[("carrot", 1), ("carrotseed", 1)]) ], 600) -entities["carrot"] = lambda: Entity(sprite="food", name="carrot", height=0.3, components={"item": Food(4)}, dataComponents=[Static("carrot"), Item]) +entities["carrot"] = lambda: Entity(sprite="food", name="carrot", height=0.3, dataComponents=[Static("carrot"), Item, Food(5)]) createCrop("radish", [ @@ -107,7 +107,7 @@ createCrop("radish", [ ) ], 10) -entities["radishes"] = lambda: Entity(sprite="food", name="radishes", height=0.3, components={"item": Food(2)}, dataComponents=[Static("radishes"), Item]) +entities["radishes"] = lambda: Entity(sprite="food", name="radishes", height=0.3, dataComponents=[Static("radishes"), Item, Food(3)]) entities["food"] = entities["radishes"] entities["sownseed"] = entities["plantedradishseed"] @@ -115,7 +115,7 @@ entities["youngplant"] = entities["youngradishplant"] entities["plant"] = entities["radishplant"] entities["seed"] = entities["radishseed"] -entities["eldritch_radish"] = lambda: Entity(sprite="food", name="eldritch radishes", height=0.3, components={"item": Food(20)}, dataComponents=[Static("eldritch_radish"), Item]) +entities["eldritch_radish"] = lambda: Entity(sprite="food", name="eldritch radishes", height=0.3, dataComponents=[Static("eldritch_radish"), Item, Food(20)]) diff --git a/asciifarm/server/gameobjects/items.py b/asciifarm/server/gameobjects/items.py index 39789e7..40736b6 100644 --- a/asciifarm/server/gameobjects/items.py +++ b/asciifarm/server/gameobjects/items.py @@ -1,8 +1,8 @@ from ..entity import Entity -from ..datacomponents import Static, Item -from ..components import Build, Equippable +from ..datacomponents import Static, Item, Equippable +from ..components import Build entities = {} @@ -15,13 +15,13 @@ entities["pebble"] = lambda: Entity(sprite="pebble", height=0.2, dataComponents= -entities["sword"] = lambda: Entity(sprite="sword", height=0.5, components={"item": Equippable("hand", {"strength": 5})}, dataComponents=[Static("sword"), Item]) +entities["sword"] = lambda: Entity(sprite="sword", height=0.5, dataComponents=[Static("sword"), Item, Equippable("hand", {"strength": 5})]) -entities["club"] = lambda: Entity(sprite="club", height=0.5, components={"item": Equippable("hand", {"strength": 3})}, dataComponents=[Static("club"), Item]) +entities["club"] = lambda: Entity(sprite="club", height=0.5, dataComponents=[Static("club"), Item, Equippable("hand", {"strength": 3})]) -entities["weapon"] = lambda strength=0, name="weapon": Entity(sprite="sword", name=name, height=0.5, components={"item": Equippable("hand", {"strength": strength})}, dataComponents=[Static("weapon", strength=strength), Item]) +entities["weapon"] = lambda strength=0, name="weapon": Entity(sprite="sword", name=name, height=0.5, dataComponents=[Static("weapon", strength=strength), Item. Equippable("hand", {"strength": strength})]) -entities["armour"] = lambda: Entity(sprite="armour", height=0.5, components={"item": Equippable("body", {"defence": 100})}, dataComponents=[Static("armour"), Item]) +entities["armour"] = lambda: Entity(sprite="armour", height=0.5, dataComponents=[Static("armour"), Item, Equippable("body", {"defence": 100})]) diff --git a/asciifarm/server/player.py b/asciifarm/server/player.py index 31da13a..e6b3504 100644 --- a/asciifarm/server/player.py +++ b/asciifarm/server/player.py @@ -71,7 +71,8 @@ class Player: for item in self.inventory.items: item.construct(roomData) for item in self.equipment.slots.values(): - item.construct(roomData) + if item is not None: + item.construct(roomData) for attr in dir(self): if attr.startswith("on_"): self.entity.addListener(attr[3:], self.__getattribute__(attr)) @@ -134,6 +135,7 @@ class Player: def control(self, action): if not self.entity or not (isinstance(action, list) or isinstance(action, tuple)) or len(action) < 1: return + print(action) self.entity.getDataComponent(Input).action = action def getHealthPair(self): @@ -220,7 +222,7 @@ class Player: "name": self.name, "roomname": self.roomname, "inventory": {"capacity": self.inventory.capacity, "items": [item.serialize().toJSON() for item in self.inventory.items]}, - "equipment": {slot: item.serialialize().toJSON() for slot, item in self.equipment.slots.items()}, + "equipment": {slot: (item.serialize().toJSON() if item is not None else None) for slot, item in self.equipment.slots.items()}, #self.equipment.toJSON(), "health": self.getHealth(), "maxhealth": self.maxHealth @@ -232,7 +234,9 @@ class Player: self.health = data["health"] self.maxHealth = data["maxhealth"] self.inventory = Inventory(data["inventory"]["capacity"], [gameobjects.createEntity(Template.fromJSON(item)) for item in data["inventory"]["items"]]) - self.equipment = Equipment({slot: gameobjects.createEntity(Template.fromJSON(item)) for slot, item in data["equipment"].items() if item is not None}) + for slot, item in data["equipment"].items(): + if item is not None: + self.equipment.slots[slot] = gameobjects.createEntity(Template.fromJSON(item)) #Equipment.fromJSON(data["equipment"]) self.roomname = data["roomname"] diff --git a/asciifarm/server/room.py b/asciifarm/server/room.py index 81f7d1e..4925eb2 100644 --- a/asciifarm/server/room.py +++ b/asciifarm/server/room.py @@ -10,7 +10,7 @@ from . import serialize from .template import Template -from .systems import fight, attacked, heal, move, controlai, control, handleevents, remove, droploot, clearinbox, trap, teleport, sound, checktimers, create, spawn +from .systems import fight, attacked, heal, move, controlai, control, handleevents, remove, droploot, clearinbox, trap, teleport, sound, checktimers, create, spawn, eat, equip class Room: @@ -84,6 +84,8 @@ class Room: teleport, fight, heal, + eat, + equip, attacked, droploot, spawn, @@ -158,7 +160,7 @@ class Room: return { "changes": [ (obj.getGround().getPos(), obj.serialize().toJSON()) - for obj in self.roomData.getPreserved()], + for obj in self.roomData.getPreserved() if obj.getGround()], "step": self.lastStepStamp} def loadPreserved(self, objects): diff --git a/asciifarm/server/system.py b/asciifarm/server/system.py index fdea12b..e116392 100644 --- a/asciifarm/server/system.py +++ b/asciifarm/server/system.py @@ -2,6 +2,7 @@ def system(components, avoid=None): + assert isinstance(components, list) or isinstance(components, tuple) def system_wrapper(func): def system_impl(roomData): entities = roomData.getEntities(components, avoid=avoid) diff --git a/asciifarm/server/systems/__init__.py b/asciifarm/server/systems/__init__.py index 0091568..2153070 100644 --- a/asciifarm/server/systems/__init__.py +++ b/asciifarm/server/systems/__init__.py @@ -14,3 +14,5 @@ from .sound import sound from .checktimers import checktimers from .create import create from .spawn import spawn +from .eat import eat +from .equip import equip diff --git a/asciifarm/server/systems/controlinput.py b/asciifarm/server/systems/controlinput.py index 4d6aa57..dac7925 100644 --- a/asciifarm/server/systems/controlinput.py +++ b/asciifarm/server/systems/controlinput.py @@ -1,5 +1,5 @@ -from ..datacomponents import Input, Fighter, Move, Faction, Interact, Inventory, Attackable, Item, Held +from ..datacomponents import Input, Fighter, Move, Faction, Interact, Inventory, Attackable, Item, UseMessage from ..system import system @system([Input, Fighter, Move]) @@ -47,7 +47,6 @@ def do_take(obj, roomData, rank): for item in objects: if roomData.getComponent(item, Item) is not None: inventory.add(item) - roomData.addComponent(item, Held(obj)) obj.trigger("inventorychange") item.unPlace() break @@ -62,7 +61,6 @@ def do_drop(obj, roomData, rank): return False item = inventory.items[rank] inventory.items.remove(item) - roomData.removeComponent(item, Held) obj.trigger("inventorychange") item.place(obj.getGround()) return True @@ -77,6 +75,7 @@ def do_use(obj, roomData, rank): onUse = roomData.getComponent(item, Item).onUse for component in onUse: roomData.addComponent(item, component) + roomData.addComponent(item, UseMessage(obj)) def do_unequip(obj, roomData, rank): inventory = roomData.getComponent(obj, Inventory) diff --git a/asciifarm/server/systems/eat.py b/asciifarm/server/systems/eat.py new file mode 100644 index 0000000..811ea31 --- /dev/null +++ b/asciifarm/server/systems/eat.py @@ -0,0 +1,16 @@ + +from ..system import system +from ..datacomponents import UseMessage, Food, Attackable, Remove, Inventory + +@system([UseMessage, Food]) +def eat(obj, roomData, use, food): + actor = use[0].actor + life = roomData.getComponent(actor, Attackable) + if life is not None: + life.heal(food.healing, obj) + roomData.addComponent(obj, Remove) + inv = roomData.getComponent(actor, Inventory) + if inv is not None: + inv.items.remove(obj) + actor.trigger("inventorychange") + diff --git a/asciifarm/server/systems/equip.py b/asciifarm/server/systems/equip.py new file mode 100644 index 0000000..1e0a0b2 --- /dev/null +++ b/asciifarm/server/systems/equip.py @@ -0,0 +1,27 @@ + +from ..system import system +from ..datacomponents import UseMessage, Equippable, Equipment, Inventory + +@system([UseMessage, Equippable]) +def equip(obj, roomData, use, equippable): + actor = use[0].actor + equipment = roomData.getComponent(actor, Equipment) + inv = roomData.getComponent(actor, Inventory) + if equipment is None or equippable.slot not in equipment.slots or inv is None: + raise Exception("attempting to equip whithout having inventory", equippable.slot, str(equipment.slots)) + if obj in inv.items: + + inv.items.remove(obj) + olditem = equipment.slots[equippable.slot] + if olditem is not None: + inv.add(olditem) + equipment.slots[equippable.slot] = obj + elif equipment.slots[equippable.slot] == obj: + if len(inventory.items) < capacity: + equipment.slots[equippable.slot] = None + inventory.add(obj) + else: + raise Exception("attempting to equip item not in inventory") + actor.trigger("inventorychange") + actor.trigger("equipmentchange") +