equipment and food are now ECS

This commit is contained in:
troido 2019-10-09 00:04:08 +02:00
parent daa712fedb
commit bffba2abb7
17 changed files with 87 additions and 97 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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}

View File

@ -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

View File

@ -0,0 +1,6 @@
class Equippable:
def __init__(self, slot, stats):
self.slot = slot
self.stats = stats

View File

@ -1,6 +0,0 @@
class Held:
def __init__(self, holder):
self.holder = holder

View File

@ -26,3 +26,7 @@ class SpawnMessage(Message):
class EatMessage(Message):
pass
class UseMessage(Message):
def __init__(self, actor):
self.actor = actor

View File

@ -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)])

View File

@ -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})])

View File

@ -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"]

View File

@ -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):

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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")