class StuffProperties: id: str name: str is_bag: bool = False filled_at: typing.Optional[float] = None filled_with_resource: typing.Optional[str] = None filled_unity: typing.Optional[Unit] = None filled_capacity: typing.Optional[float] = None weight: typing.Optional[float] = None clutter: typing.Optional[float] = None clutter_capacity: typing.Optional[float] = None image: typing.Optional[str] = None descriptions: typing.List[ActionDescriptionModel] = serpyco.field(default_factory=list) material_type: typing.Optional[str] = None abilities: typing.List[str] = serpyco.field(default_factory=list) weapon: bool = False shield: bool = False armor: bool = False estoc: int = 0 # estoc (pointe de lame) blunt: int = 0 # frappe (gourdin) sharp: int = 0 # taille (coupant de lame) protect_estoc: int = 0 protect_blunt: int = 0 protect_sharp: int = 0 damages: float = 0.0 classes: typing.List[str] = serpyco.field(default_factory=list) skills_bonus: typing.List[str] = serpyco.field(default_factory=list) def have_one_of_abilities(self, abilities: typing.List[str]) -> bool: for ability in abilities: if ability in self.abilities: return True return False
class ZoneBuildModel: row_i: int = serpyco.number_field(getter=lambda b: b.doc.zone_row_i) col_i: int = serpyco.number_field(getter=lambda b: b.doc.zone_col_i) char: str = serpyco.string_field(getter=lambda b: b.desc.char) id: int = serpyco.number_field(getter=lambda b: b.doc.id) build_id: str = serpyco.number_field(getter=lambda b: b.doc.build_id) classes: typing.List[str] = serpyco.field(default_factory=list, getter=lambda b: b.desc.classes) traversable: typing.Dict[TransportType, bool] = serpyco.field( default_factory=dict, getter=lambda b: b.desc.traversable)
class MoveZoneInfos: can_move: bool cost: float cannot_move_reasons: typing.List[str] followers_can: typing.List[CharacterModel] = serpyco.field( default_factory=list) followers_cannot: typing.List[CharacterModel] = serpyco.field( default_factory=list) followers_discreetly_can: typing.List[CharacterModel] = serpyco.field( default_factory=list) followers_discreetly_cannot: typing.List[CharacterModel] = serpyco.field( default_factory=list)
class BuildDescription: id: str name: str char: str building_char: str build_require_resources: typing.List[BuildBuildRequireResourceDescription] turn_require_resources: typing.List[BuildTurnRequireResourceDescription] power_on_require_resources: typing.List[ BuildPowerOnRequireResourceDescription] ability_ids: typing.List[str] cost: float classes: typing.List[str] = serpyco.field(default_factory=list) many: bool = False traversable: typing.Dict[TransportType, bool] = serpyco.field(default_factory=dict)
class ZoneProperties: zone_type: typing.Type[MapTileType] generation_info: GenerationInfo move_cost: float resources: typing.List[ZoneResource] stuffs: typing.List[ZoneStuff] description: str require_transport_type: typing.List[TransportType] = serpyco.field( default_factory=list) @property def resource_ids(self) -> typing.Iterator[str]: for zone_resource in self.resources: yield zone_resource.resource_id @property def stuff_ids(self) -> typing.Iterator[str]: for zone_stuff in self.stuffs: yield zone_stuff.stuff_id
class StuffModel: """existing stuff (on zone or carried)""" id: int stuff_id: str name: str zone_col_i: typing.Optional[int] = None zone_row_i: typing.Optional[int] = None is_bag: bool = False filled_at: typing.Optional[float] = None filled_unity: typing.Optional[Unit] = None filled_with_resource: typing.Optional[str] = None weight: typing.Optional[float] = None clutter: typing.Optional[float] = None clutter_capacity: typing.Optional[float] = None image: typing.Optional[str] = None carried_by: typing.Optional[str] = None stored_in: typing.Optional[int] = None ap_required: float = 0.0 ap_spent: float = 0.0 under_construction: bool = False description: str = "" weapon: bool = False shield: bool = False armor: bool = False estoc: int = 0 blunt: int = 0 sharp: int = 0 protect_estoc: int = 0 protect_blunt: int = 0 protect_sharp: int = 0 damages: float = 0.0 classes: typing.List[str] = serpyco.field(default_factory=list) @property def ready_for_use(self) -> bool: # TODO BS: is broken, etc return not self.under_construction def get_full_description(self, kernel: "Kernel") -> typing.List[str]: descriptions: typing.List[str] = [] if self.weight: descriptions.append(display_g_or_kg(self.weight)) if self.filled_at is not None: descriptions.append(f"{self.filled_at}%") if self.filled_with_resource is not None: resource_description = kernel.game.config.resources[self.filled_with_resource] descriptions.append(f"{resource_description.name}") if self.clutter: descriptions.append(f"{round(self.clutter, 3)} d'encombrement") return descriptions def get_light_description(self, kernel: "Kernel") -> typing.List[str]: descriptions: typing.List[str] = [] if self.filled_at is not None: descriptions.append(f"{self.filled_at}%") if self.filled_with_resource is not None: resource_description = kernel.game.config.resources[self.filled_with_resource] descriptions.append(f"{resource_description.name}") return descriptions def get_name_and_light_description(self, kernel: "Kernel") -> str: descriptions = self.get_light_description(kernel) if not descriptions: return self.name description = "(" + ", ".join(descriptions) + ")" return f"{self.get_name()} {description}" def get_name(self) -> str: under_construction_char = "*" if self.under_construction else "" return f"{self.name}{under_construction_char}"
class ComplexM: foo: str sub: SubM subs: typing.List[SubM] bar: int = serpyco.field(getter=ParentTestObject.bar)
class SubM: w: int y: str z: int x: int = serpyco.field(getter=get_x)
class DrinkStuffModel: stuff_id: int = serpyco.field(cast_on_load=True)
class GetCharacterAndPendingActionPathModel: character_id: str pending_action_id: int = serpyco.field(cast_on_load=True)
class PendingActionQueryModel: do: int = serpyco.field(cast_on_load=True, default=0)
class CharacterModel: id: str name: str background_story: str max_life_comp: float hunting_and_collecting_comp: float find_water_comp: float life_points: float action_points: float attack_allowed_loss_rate: int defend_allowed_loss_rate: int skills: typing.Dict[str, CharacterSkillModel] knowledges: typing.Dict[str, KnowledgeDescription] # NOTE: must be feed (like with knowledges) at creation ability_ids: typing.List[str] = serpyco.field(default_factory=list) world_col_i: int = None world_row_i: int = None zone_col_i: int = None zone_row_i: int = None feel_thirsty: bool = True dehydrated: bool = False feel_hungry: bool = True starved: bool = False tiredness: int = 0 _display_object = None bags: typing.List[StuffModel] = serpyco.field(default_factory=list) # FIXME BS NOW: fill them from doc weapon: typing.Optional[StuffModel] = None shield: typing.Optional[StuffModel] = None armor: typing.Optional[StuffModel] = None unread_event: bool = False unread_zone_message: bool = False unread_conversation: bool = False unvote_affinity_relation: bool = False unread_transactions: bool = False pending_actions: int = 0 @property def tired(self) -> bool: return self.tiredness > MINIMUM_BEFORE_TIRED def is_exhausted(self) -> bool: return self.tiredness > MINIMUM_BEFORE_EXHAUSTED @property def vulnerable(self) -> bool: return not self.is_defend_ready() def is_attack_ready(self) -> bool: return (not self.is_exhausted() and self.action_points >= FIGHT_AP_CONSUME and self.life_points > FIGHT_LP_REQUIRE) def is_defend_ready(self) -> bool: # FIXME BS: keep exhausted ? return not self.is_exhausted() and self.life_points > FIGHT_LP_REQUIRE def associate_display_object(self, display_object: "DisplayObject") -> None: self._display_object = display_object @property def force_weapon_multiplier(self) -> float: return min(MAXIMUM_FORCE_WEAPON_MULTIPLIER, self.get_skill_value(STRENGTH_SKILL_ID)) @property def display_object(self) -> "DisplayObject": if self._display_object is None: raise RollingError( "You are trying to use property which is not set") return self._display_object def get_weight_capacity(self, kernel: "Kernel") -> float: return kernel.game.config.default_weight_capacity * self.get_skill_value( STRENGTH_SKILL_ID) def get_clutter_capacity(self, kernel: "Kernel") -> float: return kernel.game.config.default_clutter_capacity + sum( [bag.clutter_capacity for bag in self.bags]) def have_one_of_abilities(self, abilities: typing.List[str]) -> bool: for ability in abilities: if ability in self.ability_ids: return True return False def get_skill_value(self, skill_id: str) -> float: return self.skills[skill_id].value def have_knowledge(self, knowledge_id: str) -> bool: return knowledge_id in self.knowledges def get_with_weapon_coeff(self, weapon: "Weapon", kernel: "Kernel") -> float: better_coeff = 1.0 for bonus_skill_id in weapon.get_bonus_with_skills(kernel): with_this_skill_bonus = self.get_skill_value(bonus_skill_id) / 2 if with_this_skill_bonus > better_coeff: better_coeff = with_this_skill_bonus return better_coeff
class WithStuffActionModel: character_id: str # FIXME BS 2019-09-09: should be int no ? action_type: ActionType action_description_id: str stuff_id: int = serpyco.field(cast_on_load=True)
class FillStuffWithResourceModel: resource_id: str = serpyco.field()
class LearnKnowledgeModel: knowledge_id: str ap: typing.Optional[int] = serpyco.field(cast_on_load=True, default=None)
class ProposeTeachKnowledgeModel: knowledge_id: str ap: typing.Optional[int] = serpyco.field(cast_on_load=True, default=None) expire: typing.Optional[int] = serpyco.field(cast_on_load=True, default=1)