diff --git a/README.md b/README.md index 8c40e6e..d734e45 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ - [ ] 性格系统设计 - [ ] 角色特殊能力 - [ ] 角色称号&绰号 +- [ ] 角色Buffs系统:增益/减益效果、状态管理 - [ ] 战斗相关 - [ ] 属性点分配 - [ ] 技能系统(功法) @@ -82,7 +83,6 @@ - [ ] 自然灾害 - [ ] 天灾 - [ ] 战争 - - [ ] 兽潮 ### ⚔️ 战斗系统 - [ ] 战斗方式设计 @@ -91,14 +91,15 @@ - [ ] 战斗规则引擎 ### 🎒 物品系统 -- [ ] 基础物品框架 -- [ ] 物品属性系统 +- ✅ 基础物品、灵石框架 - [ ] 物品交易机制 +- [ ] 经济系统 ### 🌿 生态系统 +- ✅ 动植物 +- [ ] 生物间相互影响 - [ ] 魔兽系统 -- [ ] 动植物生态 -- [ ] 生物间相互关系 +- [ ] 兽潮 ### 🤖 AI增强系统 - ✅ LLM接口集成 diff --git a/assets/screenshot.png b/assets/screenshot.png index 15d8d56..2d5c748 100644 Binary files a/assets/screenshot.png and b/assets/screenshot.png differ diff --git a/src/classes/animal.py b/src/classes/animal.py new file mode 100644 index 0000000..e1bef58 --- /dev/null +++ b/src/classes/animal.py @@ -0,0 +1,40 @@ +from dataclasses import dataclass + +from src.utils.df import game_configs + +@dataclass +class Animal: + """ + 动物 + """ + id: int + name: str + desc: str + grade: int + + def __hash__(self) -> int: + return hash(self.id) + + def __str__(self) -> str: + return self.name + +def _load_animals() -> tuple[dict[int, Animal], dict[str, Animal]]: + """从配表加载animal数据""" + animals_by_id: dict[int, Animal] = {} + animals_by_name: dict[str, Animal] = {} + + animal_df = game_configs["animal"] + for _, row in animal_df.iterrows(): + animal = Animal( + id=int(row["id"]), + name=str(row["name"]), + desc=str(row["desc"]), + grade=int(row["grade"]) + ) + animals_by_id[animal.id] = animal + animals_by_name[animal.name] = animal + + return animals_by_id, animals_by_name + +# 从配表加载animal数据 +animals_by_id, animals_by_name = _load_animals() diff --git a/src/classes/avatar.py b/src/classes/avatar.py index b5fe31d..964ced0 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -15,6 +15,8 @@ from src.classes.event import NULL_EVENT from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_PAIR from src.classes.persona import Persona, personas_by_id +from src.classes.item import Item +from src.classes.magic_stone import MagicStone from src.utils.id_generator import get_avatar_id from src.utils.config import CONFIG @@ -55,6 +57,8 @@ class Avatar: cur_action_pair: Optional[ACTION_PAIR] = None history_action_pairs: list[ACTION_PAIR] = field(default_factory=list) thinking: str = "" + magic_stone: MagicStone = field(default_factory=lambda: MagicStone(0)) # 灵石,即货币 + items: dict[Item, int] = field(default_factory=dict) def __post_init__(self): """ @@ -183,6 +187,75 @@ class Avatar: def is_in_region(self, region: Region) -> bool: return self.tile.region == region + + def add_item(self, item: Item, quantity: int = 1) -> None: + """ + 添加物品到背包 + + Args: + item: 要添加的物品 + quantity: 添加数量,默认为1 + """ + if quantity <= 0: + return + + if item in self.items: + self.items[item] += quantity + else: + self.items[item] = quantity + + def remove_item(self, item: Item, quantity: int = 1) -> bool: + """ + 从背包移除物品 + + Args: + item: 要移除的物品 + quantity: 移除数量,默认为1 + + Returns: + bool: 是否成功移除(如果物品不足则返回False) + """ + if quantity <= 0: + return True + + if item not in self.items: + return False + + if self.items[item] < quantity: + return False + + self.items[item] -= quantity + + # 如果数量为0,从字典中移除该物品 + if self.items[item] == 0: + del self.items[item] + + return True + + def has_item(self, item: Item, quantity: int = 1) -> bool: + """ + 检查是否拥有足够数量的物品 + + Args: + item: 要检查的物品 + quantity: 需要的数量,默认为1 + + Returns: + bool: 是否拥有足够数量的物品 + """ + return item in self.items and self.items[item] >= quantity + + def get_item_quantity(self, item: Item) -> int: + """ + 获取指定物品的数量 + + Args: + item: 要查询的物品 + + Returns: + int: 物品数量,如果没有该物品则返回0 + """ + return self.items.get(item, 0) def get_history_action_pairs_str(self) -> str: """ @@ -211,7 +284,17 @@ class Avatar: info = self.get_info() persona = self.persona.prompt action_space = self.get_action_space_str() - return f"{info}\n其个性为:{persona}\n决策时需参考这个角色的个性。\n该角色的动作空间及其参数为:{action_space}" + + # 添加灵石信息 + magic_stone_info = f"灵石持有情况:{str(self.magic_stone)}" + + # 添加物品信息 + if self.items: + items_info = "物品持有情况:" + ",".join([f"{item.name}x{quantity}" for item, quantity in self.items.items()]) + else: + items_info = "物品持有情况:无" + + return f"{info}\n其个性为:{persona}\n{magic_stone_info}\n{items_info}\n决策时需参考这个角色的个性。\n该角色的动作空间及其参数为:{action_space}" def get_new_avatar_from_ordinary(world: World, current_month_stamp: MonthStamp, name: str, age: Age): """ diff --git a/src/classes/item.py b/src/classes/item.py index e69de29..755dbbb 100644 --- a/src/classes/item.py +++ b/src/classes/item.py @@ -0,0 +1,40 @@ +from dataclasses import dataclass + +from src.utils.df import game_configs + +@dataclass +class Item: + """ + 物品 + """ + id: int + name: str + desc: str + grade: int + + def __str__(self) -> str: + return self.name + +def _load_items() -> tuple[dict[int, Item], dict[str, Item]]: + """从配表加载item数据""" + items_by_id: dict[int, Item] = {} + items_by_name: dict[str, Item] = {} + + item_df = game_configs["item"] + for _, row in item_df.iterrows(): + item = Item( + id=int(row["id"]), + name=str(row["name"]), + desc=str(row["desc"]), + grade=int(row["grade"]) + ) + items_by_id[item.id] = item + items_by_name[item.name] = item + + return items_by_id, items_by_name + +# 从配表加载item数据 +items_by_id, items_by_name = _load_items() + + + diff --git a/src/classes/magic_stone.py b/src/classes/magic_stone.py new file mode 100644 index 0000000..d7c981b --- /dev/null +++ b/src/classes/magic_stone.py @@ -0,0 +1,18 @@ + + +class MagicStone(int): + """ + 灵石,实际上是一个int类,代表持有的下品灵石的数量。 + 但是可以转换为中品、上品灵石。汇率为100:1 + """ + def __init__(self, value: int): + self.value = value + + def exchange(self) -> tuple[int, int, int]: + _value, _upper = divmod(self.value, 100) + _value, _middle = divmod(_value, 100) + return _upper, _middle, _value + + def __str__(self) -> str: + _upper, _middle, _value = self.exchange() + return f"上品灵石:{_upper},中品灵石:{_middle},下品灵石:{_value}" \ No newline at end of file diff --git a/src/classes/plant.py b/src/classes/plant.py new file mode 100644 index 0000000..38b25a8 --- /dev/null +++ b/src/classes/plant.py @@ -0,0 +1,40 @@ +from dataclasses import dataclass + +from src.utils.df import game_configs + +@dataclass +class Plant: + """ + 植物 + """ + id: int + name: str + desc: str + grade: int + + def __hash__(self) -> int: + return hash(self.id) + + def __str__(self) -> str: + return self.name + +def _load_plants() -> tuple[dict[int, Plant], dict[str, Plant]]: + """从配表加载plant数据""" + plants_by_id: dict[int, Plant] = {} + plants_by_name: dict[str, Plant] = {} + + plant_df = game_configs["plant"] + for _, row in plant_df.iterrows(): + plant = Plant( + id=int(row["id"]), + name=str(row["name"]), + desc=str(row["desc"]), + grade=int(row["grade"]) + ) + plants_by_id[plant.id] = plant + plants_by_name[plant.name] = plant + + return plants_by_id, plants_by_name + +# 从配表加载plant数据 +plants_by_id, plants_by_name = _load_plants() diff --git a/src/front/front.py b/src/front/front.py index a066e0d..96e33cb 100644 --- a/src/front/front.py +++ b/src/front/front.py @@ -434,10 +434,17 @@ class Front: f"位置: ({avatar.pos_x}, {avatar.pos_y})", ] - # 添加历史动作信息 - lines.append("") # 空行分隔 - lines.append("历史动作:") - lines.extend(avatar.get_history_action_pairs_str().split("\n")) + # 添加灵石信息(使用MagicStone的__str__方法显示详细信息) + lines.append(f"灵石: {str(avatar.magic_stone)}") + + # 添加物品信息 + if avatar.items: + lines.append("物品:") + for item, quantity in avatar.items.items(): + lines.append(f" {item.name} x{quantity}") + else: + lines.append("") # 空行分隔 + lines.append("物品: 无") # 添加thinking信息 if avatar.thinking: diff --git a/static/game_configs/animal.csv b/static/game_configs/animal.csv new file mode 100644 index 0000000..12a7fcd --- /dev/null +++ b/static/game_configs/animal.csv @@ -0,0 +1,3 @@ +id,name,desc,grade +1,灵兔,天性机敏的灵性兔子,毛色雪白,蕴含微弱灵力,性情温和易驯服,1 +2,魔狼,凶猛的魔性狼族,体型巨大,拥有强大的魔力和锋利的爪牙,2 diff --git a/static/game_configs/item.csv b/static/game_configs/item.csv new file mode 100644 index 0000000..77fb11e --- /dev/null +++ b/static/game_configs/item.csv @@ -0,0 +1,5 @@ +id,name,desc,grade +1,灵兔皮毛,灵性充沛的兔子皮毛,质地柔软,常用于制作防护装备,1 +2,魔狼皮毛,蕴含魔力的狼族皮毛,坚韧耐用,适合制作高级护甲,2 +3,奇草,生长在灵气充沛之地的奇异草药,具有神奇的治愈效果,1 +4,灵木,吸收天地灵气生长的珍贵木材,是制作法器的上等材料,2 diff --git a/static/game_configs/persona.csv b/static/game_configs/persona.csv index fa40259..330c643 100644 --- a/static/game_configs/persona.csv +++ b/static/game_configs/persona.csv @@ -3,4 +3,5 @@ id,name,prompt 2,无常,你是一个无常的人,目标飘忽不定,不会长期坚持一个目标。 3,怠惰,你是一个怠惰的人,你总是会拖延,不想努力,更热衷于享受人生。 4,冒险,你是一个冒险的人,你总是会冒险,喜欢刺激,总想放手一搏。 -5,随性,你是一个随性的人,你总是会随机应变,性子到哪里了就是哪里,没有一定痣规。 +5,随性,你是一个随性的人,你总是会随机应变,性子到哪里了就是哪里,没有一定之规。 +6,贪财,你是一个贪财的人,你对灵石和财富有着强烈的渴望。 diff --git a/static/game_configs/plant.csv b/static/game_configs/plant.csv new file mode 100644 index 0000000..5f1846e --- /dev/null +++ b/static/game_configs/plant.csv @@ -0,0 +1,3 @@ +id,name,desc,grade +1,奇草,生长在灵气充沛之地的奇异草药,叶片呈淡蓝色,具有神奇的治愈效果,1 +2,灵木,千年古树吸收天地灵气而成,木质坚硬且蕴含浓郁灵力,2