Example #1
0
    def _repair(self, action: Repair) -> None:
        trader = self.trader_manager.get_trader(TraderType(action.tid))
        trader_view = trader.view(self.profile)
        try:
            price_rate: float = 1 + trader_view.base.repair.price_rate / 100
        except ZeroDivisionError:
            price_rate = 1

        for repair_item in action.repairItems:
            item = self.inventory.get(repair_item.item_id)
            item_template = self.templates_repository.get_template(item.tpl)
            repair_cost_per_1_durability = item_template.props.RepairCost

            if item.upd.FaceShield is not None:
                item.upd.FaceShield.Hits = 0

            assert item.upd.Repairable is not None
            new_durability = item.upd.Repairable.Durability + repair_item.count
            item.upd.Repairable.MaxDurability = new_durability
            item.upd.Repairable.Durability = new_durability
            self.response.items.change.append(item)

            total_repair_cost: int = round(
                repair_cost_per_1_durability * price_rate * repair_item.count
            )

            assert trader_view.base.repair.currency is not None
            affected, deleted = self.inventory.take_item(
                trader_view.base.repair.currency, total_repair_cost
            )
            self.response.items.change.extend(affected)
            self.response.items.del_.extend(deleted)
Example #2
0
    def __sell_to_trader(self, action: SellToTrader) -> None:
        trader_id = action.tid
        items_to_sell = action.items
        trader = self.__trader_manager.get_trader(TraderType(trader_id))
        trader_view = trader.view(self.profile)

        items = list(self.inventory.get(i.id) for i in items_to_sell)
        price_sum: int = sum(
            trader.get_sell_price(self.inventory.get(i.id), children_items=[]).amount
            for i in items_to_sell
        )
        # price_sum: int = sum(trader.get_sell_price(item, children_items=[]).amount for item in items)

        self.response.items.del_.extend(items)
        self.inventory.remove_items(items)

        currency_item = Item(
            id=generate_item_id(),
            tpl=TemplateId(CurrencyEnum[trader_view.base.currency].value),
        )
        currency_item.upd.StackObjectsCount = price_sum

        currency_items = self.inventory.split_into_stacks(currency_item)

        for item in currency_items:
            self.inventory.place_item(item)
        self.response.items.new.extend(currency_items)
Example #3
0
    def _examine(self, action: Examine) -> None:
        item_id = action.item

        if action.fromOwner is None:
            item = self.inventory.get(item_id)
            self.profile.encyclopedia.examine(item)
            return

        if action.fromOwner.type == "Trader":
            trader_id = action.fromOwner.id

            trader_inventory = self.trader_manager.get_trader(
                TraderType(trader_id)
            ).inventory
            item = trader_inventory.get(item_id)
            self.profile.encyclopedia.examine(item)

        elif action.fromOwner.type in ("HideoutUpgrade", "HideoutProduction"):
            item_tpl_id = TemplateId(action.item)
            self.profile.encyclopedia.examine(item_tpl_id)

        elif action.fromOwner.type == "RagFair":
            try:
                offer = self.flea_market.get_offer(OfferId(action.fromOwner.id))
            except NotFoundError:
                self.response.append_error(
                    title="Item examination error", message="Offer can not be found"
                )
                return

            item = offer.root_item
            assert action.item == item.id
            self.profile.encyclopedia.examine(item)
Example #4
0
    def send_insurance_mail(
        self, items: List[Item], trader_id: TraderId, profile: Profile
    ) -> None:
        trader = self.__trader_manager.get_trader(trader_type=TraderType(trader_id))
        insurance_storage_time = int(
            datetime.timedelta(
                hours=trader.base.insurance.max_storage_time
            ).total_seconds()
        )
        insurance_storage_time = int(
            insurance_storage_time * self.__storage_time_multiplier
        )

        mail = profile.mail
        message = MailDialogueMessage(
            uid=trader_id,
            type=MailMessageType.InsuranceReturn.value,
            items=MailMessageItems.from_items(items=items),
            maxStorageTime=insurance_storage_time,
            templateId="5a8fd75188a45036844e0ae8",
            # Todo: Replace with actual date and time depending on message template_id
            systemData={"date": "Some date", "time": "Some Time"},
            hasRewards=True,
            rewardCollected=False,
        )
        mail.add_message(message=message)
Example #5
0
    def __buy_from_trader(self, action: BuyFromTrader) -> None:
        trader = self.__trader_manager.get_trader(TraderType(action.tid))

        bought_items_list = trader.buy_item(action.item_id, action.count)

        for bought_item in bought_items_list:
            item = bought_item.item
            children = bought_item.children_items

            self.inventory.place_item(item, child_items=children)

            self.response.items.new.append(item.copy(deep=True))
            self.response.items.new.extend(c.copy(deep=True) for c in children)

        # Take required items from inventory
        for scheme_item in action.scheme_items:
            self.profile.pmc.TraderStandings[
                action.tid
            ].current_sales_sum += scheme_item.count
            item = self.inventory.get(scheme_item.id)
            item.upd.StackObjectsCount -= scheme_item.count
            if not item.upd.StackObjectsCount:
                self.inventory.remove_item(item)
                self.response.items.del_.append(item)
            else:
                self.response.items.change.append(item)

        trader_view = trader.view(self.profile)
        self.response.currentSalesSums[
            action.tid
        ] = trader_view.standing.current_sales_sum
Example #6
0
async def trading_api_get_trader(
    trader_id: str,
    profile: Profile = Depends(profile_manager.with_profile),
    trader_manager: TraderManager = Depends(Provide[AppContainer.trader.manager]),
) -> TarkovSuccessResponse[dict]:
    trader = trader_manager.get_trader(TraderType(trader_id))
    trader_view = trader.view(player_profile=profile)
    return TarkovSuccessResponse(data=trader_view.base.dict(exclude_none=True))
Example #7
0
    def _insure(self, action: Insure) -> None:
        trader_type = TraderType(action.tid)
        trader = self.trader_manager.get_trader(TraderType(action.tid))
        trader_view = trader.view(self.profile)

        rubles_tpl_id = TemplateId("5449016a4bdc2d6f028b456f")
        total_price = 0
        for item_id in action.items:
            item = self.profile.inventory.get(item_id)
            total_price += trader_view.insurance_price([item])
            self.profile.add_insurance(item, trader_type)

        affected_items, deleted_items = self.profile.inventory.take_item(
            rubles_tpl_id, total_price)

        self.response.items.change.extend(affected_items)
        self.response.items.del_.extend(deleted_items)
Example #8
0
    def complete_quest(
        self,
        quest_id: str,
        templates_repository: ItemTemplatesRepository = Provide[
            AppContainer.repos.templates],
        trader_manager: TraderManager = Provide[AppContainer.trader.manager],
    ) -> None:
        quest_template = self.__quests_repository.get_quest_template(quest_id)
        quest = self.get_quest(quest_id)
        quest.status = QuestStatus.Success

        reward_items: List[Item] = []
        for reward in quest_template.rewards.Success:
            if isinstance(reward, QuestRewardItem):
                for reward_item in reward.items:
                    item_template = templates_repository.get_template(
                        reward_item)
                    stack_size: int = item_template.props.StackMaxSize

                    while reward_item.upd.StackObjectsCount > 0:
                        amount_to_split = min(
                            reward_item.upd.StackObjectsCount, stack_size)
                        reward_items.append(
                            PlayerInventory.simple_split_item(
                                reward_item, amount_to_split))

            elif isinstance(reward, QuestRewardExperience):
                exp_amount: str = reward.value
                self.profile.receive_experience(int(exp_amount))

            elif isinstance(reward, QuestRewardTraderStanding):
                standing_change = float(reward.value)
                trader_id = reward.target

                trader = trader_manager.get_trader(TraderType(trader_id))
                trader_view = trader.view(player_profile=self.profile)
                standing = trader_view.standing
                standing.current_standing += standing_change

            elif isinstance(reward, QuestRewardAssortUnlock):
                # We're checking for quest assort when generating it for specific player
                pass

            else:
                raise ValueError(
                    f"Unknown reward: {reward.__class__.__name__} {reward}")

        message = MailDialogueMessage(
            uid=quest_template.traderId,
            type=StrictInt(MailMessageType.QuestSuccess.value),
            templateId=
            "5ab0f32686f7745dd409f56b",  # TODO: Right now this is a placeholder
            systemData={},
            items=MailMessageItems.from_items(reward_items),
            hasRewards=True,
        )
        self.profile.mail.add_message(message)
Example #9
0
async def get_trader_assort(
    trader_id: str,
    profile: Profile = Depends(profile_manager.with_profile_readonly),
    trader_manager: TraderManager = Depends(Provide[AppContainer.trader.manager]),
) -> Union[TarkovSuccessResponse[TraderAssortResponse], TarkovErrorResponse]:
    trader = trader_manager.get_trader(TraderType(trader_id))
    view = trader.view(player_profile=profile)

    assort_response = TraderAssortResponse(
        barter_scheme=view.barter_scheme.__root__,
        items=view.assort,
        loyal_level_items=view.loyal_level_items,
    )
    return TarkovSuccessResponse(data=assort_response)
Example #10
0
async def items_list_cost(
    request: InsuranceListCostRequest,
    profile: Profile = Depends(with_profile),
    trader_manager: TraderManager = Depends(
        Provide[AppContainer.trader.manager]),
) -> Union[TarkovSuccessResponse[Dict[str, dict]], TarkovErrorResponse]:
    insurance_data: Dict[str, dict] = {}

    for trader_id in request.traders:
        trader = trader_manager.get_trader(TraderType(trader_id))
        trader_view = trader.view(player_profile=profile)
        trader_items: Dict[TemplateId, int] = {}

        for item_id in request.items:
            item = profile.inventory.get(item_id)
            trader_items[item.tpl] = trader_view.insurance_price([item])

        insurance_data[trader_id] = trader_items

    return TarkovSuccessResponse(data=insurance_data)
Example #11
0
async def get_user_assort_price(
    trader_id: str,
    profile: Profile = Depends(profile_manager.with_profile_readonly),
    trader_manager: TraderManager = Depends(Provide[AppContainer.trader.manager]),
) -> Union[TarkovSuccessResponse[Dict[ItemId, List[List[dict]]]], TarkovErrorResponse]:
    trader = trader_manager.get_trader(TraderType(trader_id))
    items = {}

    for item in profile.inventory.items.values():
        if item.parent_id != profile.inventory.root_id:
            continue
        if not trader.can_sell(item):
            continue

        children_items = profile.inventory.iter_item_children_recursively(item)
        price = trader.get_sell_price(item, children_items=children_items)
        items[item.id] = [[{"_tpl": price.template_id, "count": price.amount}]]

    # TODO: Calculate price for items to sell in specified trader
    # output is { "item._id": [[{ "_tpl": "", "count": 0 }]] }
    return TarkovSuccessResponse(data=items)