def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel") -> typing.List[CharacterActionLink]: actions: typing.List[CharacterActionLink] = [] for fill_acceptable_type in self._kernel.game.config.fill_with_material_ids: for resource in self._kernel.game.world_manager.get_resource_on_or_around( world_row_i=character.world_row_i, world_col_i=character.world_col_i, zone_row_i=character.zone_row_i, zone_col_i=character.zone_col_i, material_type=fill_acceptable_type, ): query_params = self.input_model(resource_id=resource.id) actions.append( CharacterActionLink( name=f"Remplir {stuff.name} avec {resource.name}", link=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.FILL_STUFF, stuff_id=stuff.id, query_params=self.input_model_serializer.dump( query_params), action_description_id=self._description.id, ), cost=self.get_cost(character, stuff), )) return actions
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel") -> typing.List[CharacterActionLink]: accept_resources_ids = [ rd.id for rd in self._description.properties["accept_resources"] ] if (stuff.filled_with_resource is not None and stuff.filled_with_resource in accept_resources_ids): query_params = self.input_model(stuff_id=stuff.id) resource_description = self._kernel.game.config.resources[ stuff.filled_with_resource] return [ CharacterActionLink( name=f"Boire {resource_description.name}", link=get_with_stuff_action_url( character.id, ActionType.DRINK_STUFF, query_params=self.input_model_serializer.dump( query_params), stuff_id=stuff.id, action_description_id=self._description.id, ), cost=self.get_cost(character, stuff), ) ] return []
def with_multiple_carried_stuffs( action: "WithStuffAction", kernel: "Kernel", character: "CharacterModel", stuff: "StuffModel", input_: typing.Any, action_type: "ActionType", do_for_one_func: typing.Callable[ ["CharacterModel", "StuffModel", typing.Any], typing.List["Part"]], title: str, success_parts: typing.List["Part"], ) -> Description: all_carried = kernel.stuff_lib.get_carried_by(character.id, stuff_id=stuff.stuff_id) if len(all_carried) > 1 and input_.quantity is None: return Description( title=title, items=[ Part( text= f"Vous possedez {len(all_carried)} {stuff.name}, éxécuter cette action sur combien ?" ), Part( is_form=True, form_action=get_with_stuff_action_url( character_id=character.id, action_type=action_type, stuff_id=stuff.id, query_params=action.input_model_serializer.dump( input_), action_description_id=action.description.id, ), submit_label="Continuer", form_values_in_query=True, items=[ Part(label="Quantité", name="quantity", type_=Type.NUMBER, default_value="1") ], ), Part(is_link=True, label=f"Faire ça avec les {len(all_carried)}"), ], ) if input_.quantity is not None: do_it_count = input_.quantity else: do_it_count = 1 parts = [] for i in range(do_it_count): parts.extend(do_for_one_func(character, all_carried[i], input_)) return Description(title=title, items=parts + success_parts)
async def _use_as(self, web: TestClient, action: ActionType, character_id: str, stuff_id: int): resp = await web.post( get_with_stuff_action_url( character_id=character_id, action_type=action, stuff_id=stuff_id, query_params={}, # WARNING: this is description id but in config action have same value action_description_id=action.value, )) assert 200 == resp.status
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel" ) -> typing.List[CharacterActionLink]: return [ CharacterActionLink( name=f"Continuer le travail", link=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.CONTINUE_STUFF_CONSTRUCTION, action_description_id=self._description.id, query_params={}, stuff_id=stuff.id, ), cost=self.get_cost(character, stuff), merge_by="continue_craft", ) ]
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel") -> typing.List[CharacterActionLink]: actions: typing.List[CharacterActionLink] = [ CharacterActionLink( name=f"Laisser {stuff.name} ici", link=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.DROP_STUFF, stuff_id=stuff.id, query_params={}, action_description_id=self._description.id, ), cost=self.get_cost(character, stuff), ) ] return actions
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel" ) -> typing.List[CharacterActionLink]: actions: typing.List[CharacterActionLink] = [ CharacterActionLink( name=f"Ne plus utiliser {stuff.name} comme armure/equipement", link=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.NOT_USE_AS_ARMOR, stuff_id=stuff.id, query_params={}, action_description_id=self._description.id, ), cost=self.get_cost(character, stuff), ) ] return actions
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel" ) -> typing.List[CharacterActionLink]: actions: typing.List[CharacterActionLink] = [ CharacterActionLink( name=f"Utiliser {stuff.name} comme bouclier", link=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.USE_AS_SHIELD, stuff_id=stuff.id, query_params={}, action_description_id=self._description.id, ), cost=self.get_cost(character, stuff), ) ] return actions
def perform( self, character: "CharacterModel", stuff: "StuffModel", input_: CraftInput ) -> Description: if input_.quantity is None: return Description( title=self._description.name, items=[ Part( is_form=True, form_values_in_query=True, form_action=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.CRAFT_STUFF_WITH_STUFF, stuff_id=stuff.id, query_params=self.input_model_serializer.dump(input_), action_description_id=self._description.id, ), items=[ Part(label=f"Quelle quantité ?", type_=Type.NUMBER, name="quantity") ], ) ], ) cost = self.get_cost(character, stuff=stuff, input_=input_) self._perform( character, description=self._description, input_=input_, cost=cost, dry_run=True ) self._perform( character, description=self._description, input_=input_, cost=cost, dry_run=False ) return Description( title="Action effectué avec succès", footer_links=[ Part(is_link=True, go_back_zone=True, label="Retourner à l'écran de déplacements"), Part( is_link=True, label="Voir l'inventaire", form_action=f"/_describe/character/{character.id}/inventory", classes=["primary"], ), ], force_back_url=f"/_describe/character/{character.id}/on_place_actions", )
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel") -> typing.List[CharacterActionLink]: if stuff.stuff_id in self._description.properties["accept_stuff_ids"]: return [ CharacterActionLink( name=f"Manger {stuff.name}", link=get_with_stuff_action_url( character.id, ActionType.EAT_STUFF, query_params={}, stuff_id=stuff.id, action_description_id=self._description.id, ), cost=self.get_cost(character, stuff), ) ] return []
def get_character_actions( self, character: "CharacterModel", stuff: "StuffModel" ) -> typing.List[CharacterActionLink]: try: self.check_is_possible(character, stuff) except ImpossibleAction: return [] return [ # FIXME BS NOW: all CharacterActionLink must generate a can_be_back_url=True CharacterActionLink( name=self._description.name, link=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.CRAFT_STUFF_WITH_STUFF, action_description_id=self._description.id, stuff_id=stuff.id, query_params={}, ), cost=self.get_cost(character, stuff), ) ]
def perform( self, character: "CharacterModel", stuff: "StuffModel", input_: ContinueStuffModel ) -> Description: bonus = character.get_skill_value("intelligence") + character.get_skill_value("crafts") bonus_divider = max(1.0, (bonus * 2) / DEFAULT_MAXIMUM_SKILL) remain_ap = stuff.ap_required - stuff.ap_spent remain_ap_for_character = remain_ap / bonus_divider if not input_.ap: return Description( title=f"Continuer de travailler sur {stuff.name}", items=[ Part( is_form=True, form_values_in_query=True, form_action=get_with_stuff_action_url( character_id=character.id, action_type=ActionType.CONTINUE_STUFF_CONSTRUCTION, query_params={}, action_description_id=self._description.id, stuff_id=stuff.id, ), items=[ Part( text=f"Il reste {round(remain_ap, 3)} PA à passer ({round(remain_ap_for_character, 3)} avec vos bonus)" ), Part( label=f"Combien de points d'actions dépenser ?", type_=Type.NUMBER, name="ap", ), ], ) ], ) consume_ap = min(remain_ap, input_.ap * bonus_divider) stuff_doc = self._kernel.stuff_lib.get_stuff_doc(stuff.id) stuff_doc.ap_spent = float(stuff_doc.ap_spent) + consume_ap self._kernel.character_lib.reduce_action_points(character.id, consume_ap, commit=False) if stuff_doc.ap_spent >= stuff_doc.ap_required: stuff_doc.under_construction = False title = f"Construction de {stuff.name} terminé" else: title = f"Construction de {stuff.name} avancé" self._kernel.server_db_session.commit() return Description( title=title, footer_links=[ Part(is_link=True, go_back_zone=True, label="Retourner à l'écran de déplacements"), Part( is_link=True, label="Voir l'objet commencé", form_action=DESCRIBE_LOOK_AT_STUFF_URL.format( character_id=character.id, stuff_id=stuff_doc.id ), classes=["primary"], ), ], force_back_url=f"/_describe/character/{character.id}/on_place_actions", )