Exemple #1
0
 def get_full_description(self, kernel: "Kernel") -> str:
     weight = display_g_or_kg(self.weight)
     quantity_str = quantity_to_str(self.quantity, self.unit, kernel=kernel)
     return (
         f"{self.name} "
         f"({quantity_str}, {weight}, {round(self.clutter, 3)} d'encombrement)"
     )
Exemple #2
0
    def get_name(self, kernel: "Kernel", quantity: bool = False) -> str:
        quantity_str = ""

        if self.resource_id:
            resource_properties = kernel.game.config.resources[
                self.resource_id]
            if quantity:
                quantity_str = quantity_to_str(self.quantity,
                                               resource_properties.unit,
                                               kernel)
                quantity_str = f" ({quantity_str})"
            return f"{resource_properties.name}{quantity_str}"

        stuff_properties = kernel.game.stuff_manager.get_stuff_properties_by_id(
            self.stuff_id)
        if quantity:
            quantity_str = f" ({round(self.quantity)})"
        return f"{stuff_properties.name}{quantity_str}"
Exemple #3
0
    async def _describe(self, request: Request,
                        hapic_data: HapicData) -> Description:
        # TODO BS 2019-09-30: check current char and near this build
        character = self._kernel.character_lib.get(
            hapic_data.path.character_id)
        build_doc = self._kernel.build_lib.get_build_doc(
            hapic_data.path.build_id)
        build_description = self._kernel.game.config.builds[build_doc.build_id]
        character_actions = self._kernel.build_lib.get_on_build_actions(
            character, hapic_data.path.build_id)

        on_construction = ""
        if build_doc.under_construction:
            on_construction = " (en construction)"

        carried_resources = self._kernel.resource_lib.get_stored_in_build(
            hapic_data.path.build_id)
        carried_in = []
        for carried_resource in carried_resources:
            resource_description = self._kernel.game.config.resources[
                carried_resource.id]
            quantity_str = quantity_to_str(carried_resource.quantity,
                                           unit=resource_description.unit,
                                           kernel=self._kernel)
            carried_in.append(
                Part(text=f"- {resource_description.name} ({quantity_str})"))
        if carried_in:
            carried_in.insert(0, Part(text="Contient des resources:"))
            carried_in.insert(1, Part(text=""))
            carried_in.append(Part(text=" "))

        parts = carried_in
        parts.extend([
            Part(
                text=action.get_as_str(),
                form_action=action.link,
                is_link=True,
                link_group_name=action.group_name,
            ) for action in character_actions
        ])

        return Description(title=f"{build_description.name}{on_construction}",
                           items=parts,
                           can_be_back_url=True)
Exemple #4
0
    def check_request_is_possible(
        self, character: "CharacterModel", input_: BeginStuffModel
    ) -> None:
        self.check_is_possible(character)
        check_common_is_possible(self._kernel, description=self._description, character=character)

        cost = self.get_cost(character)
        if character.action_points < cost:
            raise ImpossibleAction(
                f"{character.name} no possède pas assez de points d'actions "
                f"({round(cost, 2)} nécessaires)"
            )

        for consume in self._description.properties["consume"]:
            if "resource" in consume:
                resource_id = consume["resource"]
                resource_description = self._kernel.game.config.resources[resource_id]
                quantity = consume["quantity"]
                quantity_str = quantity_to_str(quantity, resource_description.unit, self._kernel)
                if not self._kernel.resource_lib.have_resource(
                    character.id, resource_id=resource_id, quantity=quantity
                ):
                    resource_description = self._kernel.game.config.resources[resource_id]
                    raise ImpossibleAction(
                        f"Vous ne possédez pas assez de {resource_description.name}: {quantity_str} nécessaire(s)"
                    )

            elif "stuff" in consume:
                stuff_id = consume["stuff"]
                quantity = consume["quantity"]
                if (
                    self._kernel.stuff_lib.have_stuff_count(character.id, stuff_id=stuff_id)
                    < quantity
                ):
                    stuff_properties = self._kernel.game.stuff_manager.get_stuff_properties_by_id(
                        stuff_id
                    )
                    raise ImpossibleAction(
                        f"Vous ne possédez pas assez de {stuff_properties.name}: {quantity} nécessaire(s)"
                    )
Exemple #5
0
    def check_request_is_possible(self, character: "CharacterModel", input_: BuildModel) -> None:
        check_common_is_possible(
            kernel=self._kernel, description=self._description, character=character
        )
        build_id = self._description.properties["build_id"]
        build_description = self._kernel.game.config.builds[build_id]

        if character.action_points < self.get_cost(character, input_):
            raise ImpossibleAction("Pas assez de points d'actions")

        for require in build_description.build_require_resources:
            if not self._kernel.resource_lib.have_resource(
                character.id, resource_id=require.resource_id, quantity=require.quantity
            ):
                resource_properties = self._kernel.game.config.resources[require.resource_id]
                required_quantity_str = quantity_to_str(
                    require.quantity, resource_properties.unit, self._kernel
                )
                raise ImpossibleAction(
                    f"Vous ne possedez pas assez de {resource_properties.name} "
                    f"({required_quantity_str} requis)"
                )
Exemple #6
0
    def get_character_actions(
        self, character: "CharacterModel", build_id: int
    ) -> typing.List[CharacterActionLink]:
        actions: typing.List[CharacterActionLink] = []
        build_doc = self._kernel.build_lib.get_build_doc(build_id)
        build_description = self._kernel.game.config.builds[build_doc.build_id]

        for required_resource in build_description.build_require_resources:
            resource_description, left, left_percent = self.get_resource_infos(
                self._kernel, required_resource, build_doc=build_doc
            )
            if left <= 0:
                continue

            left_str = quantity_to_str(left, resource_description.unit, kernel=self._kernel)

            query_params = BringResourcesOnBuild.input_model_serializer.dump(
                BringResourcesOnBuild.input_model(resource_id=required_resource.resource_id)
            )
            name = (
                f"Apporter {resource_description.name} pour la construction "
                f"(manque {left_str} soit {round(left_percent)}%)"
            )
            actions.append(
                CharacterActionLink(
                    name=name,
                    link=get_with_build_action_url(
                        character_id=character.id,
                        build_id=build_id,
                        action_type=ActionType.BRING_RESOURCE_ON_BUILD,
                        action_description_id=self._description.id,
                        query_params=query_params,
                    ),
                    cost=None,
                )
            )

        return actions
Exemple #7
0
    def perform(
        self, character: "CharacterModel", build_id: int, input_: typing.Any
    ) -> Description:
        build_doc = self._kernel.build_lib.get_build_doc(build_id)

        if input_.quantity is None:
            build_description = self._kernel.game.config.builds[build_doc.build_id]
            required_resource = next(
                (
                    brr
                    for brr in build_description.build_require_resources
                    if brr.resource_id == input_.resource_id
                )
            )
            resource_description, left, left_percent = self.get_resource_infos(
                self._kernel, required_resource, build_doc=build_doc
            )
            left_str = quantity_to_str(left, resource_description.unit, kernel=self._kernel)
            unit_str = self._kernel.translation.get(resource_description.unit)

            return Description(
                title=f"Cette construction nécessite encore {left_str} "
                f"de {resource_description.name} (soit {round(left_percent)}%)",
                can_be_back_url=True,
                items=[
                    Part(
                        is_form=True,
                        form_values_in_query=True,
                        form_action=get_with_build_action_url(
                            character_id=character.id,
                            build_id=build_id,
                            action_type=ActionType.BRING_RESOURCE_ON_BUILD,
                            action_description_id=self._description.id,
                            query_params=self.input_model_serializer.dump(input_),
                        ),
                        items=[
                            Part(
                                label=f"Quantité ({unit_str}) ?", type_=Type.NUMBER, name="quantity"
                            )
                        ],
                    )
                ],
            )

        resource_description = self._kernel.game.config.resources[input_.resource_id]
        try:
            self._kernel.resource_lib.reduce_carried_by(
                character.id, resource_id=input_.resource_id, quantity=input_.quantity, commit=False
            )
        except (NotEnoughResource, NoCarriedResource):
            raise ImpossibleAction(
                f"{character.name} ne possède pas assez de {resource_description.name}"
            )

        self._kernel.resource_lib.add_resource_to(
            build_id=build_doc.id,
            resource_id=input_.resource_id,
            quantity=input_.quantity,
            commit=False,
        )
        self._kernel.server_db_session.commit()

        build_description = self._kernel.game.config.builds[build_doc.build_id]
        quantity_str = quantity_to_str(
            input_.quantity, resource_description.unit, kernel=self._kernel
        )

        return Description(
            title=f"{quantity_str} {resource_description.name} déposé pour {build_description.name}",
            items=[
                Part(is_link=True, go_back_zone=True, label="Retourner à l'écran de déplacements"),
                Part(
                    label="Voir le batiment",
                    is_link=True,
                    form_action=DESCRIBE_BUILD.format(
                        build_id=build_doc.id, character_id=character.id
                    ),
                ),
            ],
            force_back_url=f"/_describe/character/{character.id}/build_actions",
        )
Exemple #8
0
    def _perform(
        self,
        character: "CharacterModel",
        description: ActionDescriptionModel,
        input_: CraftInput,
        cost: float,
        dry_run: bool = True,
    ) -> None:
        if character.action_points < cost:
            raise ImpossibleAction(
                f"{character.name} no possède pas assez de points d'actions "
                f"({round(cost, 2)} nécessaires)"
            )

        carried_resources = self._kernel.resource_lib.get_carried_by(character.id)
        carried_stuffs = self._kernel.stuff_lib.get_carried_by(character.id)

        for require in description.properties["require"]:
            if "stuff" in require:
                required_quantity = input_.quantity * int(require["quantity"])
                stuff_id = require["stuff"]
                stuff_properties = self._kernel.game.stuff_manager.get_stuff_properties_by_id(
                    stuff_id
                )
                carried_stuffs = [c for c in carried_stuffs if c.stuff_id == stuff_id]
                owned_quantity = len(carried_stuffs)

                if owned_quantity < required_quantity:
                    raise ImpossibleAction(
                        f"Vous ne possédez pas assez de {stuff_properties.name}: {required_quantity} nécessaire(s)"
                    )

                if not dry_run:
                    for i in range(required_quantity):
                        stuff_to_destroy = carried_stuffs[i]
                        self._kernel.stuff_lib.destroy(stuff_to_destroy.id)

            elif "resource" in require:
                required_quantity = input_.quantity * require["quantity"]
                resource_id = require["resource"]
                resource_properties = self._kernel.game.config.resources[resource_id]
                try:
                    carried_resource = next((c for c in carried_resources if c.id == resource_id))
                except StopIteration:
                    raise ImpossibleAction(f"Vous ne possédez pas de {resource_properties.name}")
                if carried_resource.quantity < required_quantity:
                    missing_quantity_str = quantity_to_str(
                        kernel=self._kernel,
                        quantity=(required_quantity - carried_resource.quantity),
                        unit=carried_resource.unit,
                    )
                    raise ImpossibleAction(
                        f"Vous ne possédez pas assez de {carried_resource.name}: {missing_quantity_str} nécessaire(s)"
                    )

                if not dry_run:
                    self._kernel.resource_lib.reduce_carried_by(
                        character_id=character.id,
                        resource_id=resource_id,
                        quantity=required_quantity,
                    )

        if dry_run:
            return

        for produce in description.properties["produce"]:
            stuff_id = produce["stuff"]
            quantity = produce["quantity"]
            stuff_properties = self._kernel.game.stuff_manager.get_stuff_properties_by_id(stuff_id)

            for i in range(int(quantity)):
                stuff_doc = self._kernel.stuff_lib.create_document_from_stuff_properties(
                    properties=stuff_properties,
                    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,
                )
                self._kernel.stuff_lib.add_stuff(stuff_doc, commit=False)
                self._kernel.stuff_lib.set_carried_by__from_doc(
                    stuff_doc, character_id=character.id, commit=False
                )
        self._kernel.character_lib.reduce_action_points(
            character_id=character.id, cost=cost, commit=False
        )
        self._kernel.server_db_session.commit()
Exemple #9
0
    def perform(self, character: "CharacterModel", input_: BeginStuffModel) -> Description:
        if not input_.description:
            require_txts = []
            for consume in self._description.properties["consume"]:
                if "resource" in consume:
                    resource_id = consume["resource"]
                    resource_description = self._kernel.game.config.resources[resource_id]
                    quantity_str = quantity_to_str(
                        consume["quantity"], resource_description.unit, self._kernel
                    )
                    require_txts.append(f"{quantity_str} de {resource_description.name}")

                elif "stuff" in consume:
                    stuff_id = consume["stuff"]
                    stuff_properties = self._kernel.game.stuff_manager.get_stuff_properties_by_id(
                        stuff_id
                    )
                    require_txts.append(f"{consume['quantity']} de {stuff_properties.name}")

            return Description(
                title=f"Commencer {self._description.name}",
                items=[
                    Part(
                        is_form=True,
                        form_values_in_query=True,
                        form_action=get_character_action_url(
                            character_id=character.id,
                            action_type=ActionType.BEGIN_STUFF_CONSTRUCTION,
                            query_params={},
                            action_description_id=self._description.id,
                        ),
                        items=[Part(text="Consommera :")]
                        + [Part(text=txt) for txt in require_txts]
                        + [
                            Part(
                                label=f"Vous pouvez fournir une description de l'objet",
                                type_=Type.STRING,
                                name="description",
                                default_value=self._description.properties["default_description"],
                            )
                        ],
                    )
                ],
            )

        for consume in self._description.properties["consume"]:
            if "resource" in consume:
                resource_id = consume["resource"]
                self._kernel.resource_lib.reduce_carried_by(
                    character.id,
                    resource_id=resource_id,
                    quantity=consume["quantity"],
                    commit=False,
                )

            elif "stuff" in consume:
                stuff_id = consume["stuff"]
                carried_stuffs = self._kernel.stuff_lib.get_carried_by(
                    character.id, stuff_id=stuff_id
                )
                for i in range(consume["quantity"]):
                    self._kernel.stuff_lib.destroy(carried_stuffs[i].id, commit=False)

        stuff_id = self._description.properties["produce_stuff_id"]
        stuff_properties = self._kernel.game.stuff_manager.get_stuff_properties_by_id(stuff_id)
        stuff_doc = self._kernel.stuff_lib.create_document_from_stuff_properties(
            properties=stuff_properties,
            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,
        )
        stuff_doc.description = input_.description or ""
        stuff_doc.carried_by_id = character.id
        stuff_doc.ap_spent = 0.0
        stuff_doc.ap_required = self._description.properties["craft_ap"]
        stuff_doc.under_construction = True
        self._kernel.stuff_lib.add_stuff(stuff_doc, commit=False)
        self._kernel.character_lib.reduce_action_points(
            character.id, cost=self.get_cost(character), commit=False
        )
        self._kernel.server_db_session.commit()

        return Description(
            title=f"{stuff_properties.name} commencé",
            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",
        )