예제 #1
0
def test_finds_locations(
    inventory: PlayerInventory,
    item_templates_repository: ItemTemplatesRepository = Provide[
        AppContainer.repos.templates],
    item_factory: ItemFactory = Provide[AppContainer.items.factory],
) -> None:
    # Should be able to completely fill EOD stash with PSUs
    width, height = inventory.grid_size
    psu_template = item_templates_repository.get_template(
        TemplateId("57347c2e24597744902c94a1"))
    for i in range((width * height) // (2 * 2)):
        psu, _ = item_factory.create_item(psu_template)
        inventory.place_item(psu)

    with pytest.raises(NoSpaceError):
        psu, _ = item_factory.create_item(psu_template)
        inventory.place_item(psu)
예제 #2
0
def test_should_not_be_able_to_place_items_out_of_bounds(
    inventory: PlayerInventory,
    test_coords: Tuple[int, int],
    item_templates_repository: ItemTemplatesRepository = Provide[
        AppContainer.repos.templates],
    item_factory: ItemFactory = Provide[AppContainer.items.factory],
) -> None:
    magbox = item_factory.create_item(
        item_templates_repository.get_template(
            TemplateId("5c127c4486f7745625356c13")))[0]
    x, y = test_coords
    with pytest.raises(PlayerInventory.InvalidItemLocation):
        inventory.place_item(
            item=magbox,
            location=ItemInventoryLocation(
                x=x, y=y, r=ItemOrientationEnum.Horizontal.value),
        )
예제 #3
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)
예제 #4
0
    def read(self) -> None:
        if any(
            not path.exists()
            for path in (self.pmc_profile_path, self.scav_profile_path)
        ):
            raise Profile.ProfileDoesNotExistsError

        self.pmc = ProfileModel.parse_file(self.pmc_profile_path)
        self.scav = ProfileModel.parse_file(self.scav_profile_path)

        self.encyclopedia = self.__encyclopedia_factory(profile=self)
        self.inventory = PlayerInventory(profile=self)
        self.inventory.read()

        self.quests = self.__quests_factory(profile=self)

        self.hideout = self.__hideout_factory(profile=self)
        self.hideout.read()

        self.mail = Mail(profile=self, notifier_service=self.__notifier_service)
        self.mail.read()
예제 #5
0
파일: profile.py 프로젝트: socek/jet_py
    def read(
        self,
        notifier_service: NotifierService = Provide[
            AppContainer.notifier.service]
    ) -> None:
        if any(not path.exists()
               for path in (self.pmc_profile_path, self.scav_profile_path)):
            raise Profile.ProfileDoesNotExistsError

        self.pmc = ProfileModel.parse_file(self.pmc_profile_path)
        self.scav = ProfileModel.parse_file(self.scav_profile_path)

        self.encyclopedia = Encyclopedia(profile=self)
        self.inventory = PlayerInventory(profile=self)
        self.inventory.read()

        self.quests = Quests(profile=self)

        self.hideout = Hideout(profile=self)
        self.hideout.read()

        self.mail = Mail(self, notifier_service)
        self.mail.read()
예제 #6
0
class Profile:
    class ProfileDoesNotExistsError(Exception):
        pass

    pmc: ProfileModel
    scav: ProfileModel

    hideout: Hideout
    quests: Quests
    inventory: PlayerInventory
    encyclopedia: Encyclopedia
    mail: Mail

    def __init__(
        self,
        profile_dir: Path,
        profile_id: str,
        encyclopedia_factory: Callable[..., Encyclopedia],
        hideout_factory: Callable[..., Hideout],
        quests_factory: Callable[..., Quests],
        notifier_service: NotifierService,
    ):
        self.__encyclopedia_factory = encyclopedia_factory
        self.__hideout_factory = hideout_factory
        self.__quests_factory = quests_factory
        self.__notifier_service = notifier_service

        self.profile_dir = profile_dir
        self.profile_id = profile_id

        self.pmc_profile_path = self.profile_dir.joinpath("pmc_profile.json")
        self.scav_profile_path = self.profile_dir.joinpath("scav_profile.json")

    def add_insurance(self, item: Item, trader: TraderType) -> None:
        # TODO: Move this function into IInsuranceService
        self.pmc.InsuredItems.append(
            ItemInsurance(item_id=item.id, trader_id=trader.value)
        )

    def receive_experience(self, amount: int) -> None:
        self.pmc.Info.Experience += amount

    def read(self) -> None:
        if any(
            not path.exists()
            for path in (self.pmc_profile_path, self.scav_profile_path)
        ):
            raise Profile.ProfileDoesNotExistsError

        self.pmc = ProfileModel.parse_file(self.pmc_profile_path)
        self.scav = ProfileModel.parse_file(self.scav_profile_path)

        self.encyclopedia = self.__encyclopedia_factory(profile=self)
        self.inventory = PlayerInventory(profile=self)
        self.inventory.read()

        self.quests = self.__quests_factory(profile=self)

        self.hideout = self.__hideout_factory(profile=self)
        self.hideout.read()

        self.mail = Mail(profile=self, notifier_service=self.__notifier_service)
        self.mail.read()

    def write(self) -> None:
        self.hideout.write()
        self.mail.write()
        self.inventory.write()

        atomic_write(self.pmc.json(exclude_defaults=True), self.pmc_profile_path)
        atomic_write(self.scav.json(exclude_defaults=True), self.scav_profile_path)

    def update(self) -> None:
        self.hideout.update()
예제 #7
0
파일: conftest.py 프로젝트: socek/jet_py
 def _make_inventory(inventory_path: str) -> PlayerInventory:
     target_inventory = InventoryModel.parse_file(inventory_path)
     with patch.object(player_profile.pmc, "Inventory", target_inventory):
         inventory = PlayerInventory(player_profile)
         inventory.read()
     return inventory
예제 #8
0
파일: conftest.py 프로젝트: socek/jet_py
def inventory(player_profile: Profile) -> PlayerInventory:
    inventory = PlayerInventory(player_profile)
    inventory.read()
    return inventory
예제 #9
0
def test_places_items(inventory: PlayerInventory,
                      random_items: List[Item]) -> None:
    for item in random_items:
        inventory.place_item(item)

    assert all(item in inventory.items.values() for item in random_items)
예제 #10
0
파일: profile.py 프로젝트: socek/jet_py
class Profile:
    # pylint: disable=too-many-instance-attributes
    # Disabling that in case of profile is reasonable

    class ProfileDoesNotExistsError(Exception):
        pass

    pmc: ProfileModel
    scav: ProfileModel

    hideout: Hideout
    quests: Quests
    inventory: PlayerInventory
    encyclopedia: Encyclopedia
    mail: Mail

    def __init__(self, profile_id: str):
        self.profile_id = profile_id

        self.profile_dir = root_dir.joinpath("resources", "profiles",
                                             profile_id)

        self.pmc_profile_path = self.profile_dir.joinpath("pmc_profile.json")
        self.scav_profile_path = self.profile_dir.joinpath("scav_profile.json")

    @staticmethod
    def exists(profile_id: str) -> bool:
        return root_dir.joinpath("resources", "profiles", profile_id).exists()

    def add_insurance(self, item: Item, trader: TraderType) -> None:
        self.pmc.InsuredItems.append(
            ItemInsurance(item_id=item.id, trader_id=trader.value))

        #  Todo remove insurance from items that aren't present in inventory after raid

    def receive_experience(self, amount: int) -> None:
        self.pmc.Info.Experience += amount

    @inject
    def read(
        self,
        notifier_service: NotifierService = Provide[
            AppContainer.notifier.service]
    ) -> None:
        if any(not path.exists()
               for path in (self.pmc_profile_path, self.scav_profile_path)):
            raise Profile.ProfileDoesNotExistsError

        self.pmc = ProfileModel.parse_file(self.pmc_profile_path)
        self.scav = ProfileModel.parse_file(self.scav_profile_path)

        self.encyclopedia = Encyclopedia(profile=self)
        self.inventory = PlayerInventory(profile=self)
        self.inventory.read()

        self.quests = Quests(profile=self)

        self.hideout = Hideout(profile=self)
        self.hideout.read()

        self.mail = Mail(self, notifier_service)
        self.mail.read()

    def write(self) -> None:
        self.hideout.write()
        self.mail.write()
        self.inventory.write()

        atomic_write(self.pmc.json(exclude_defaults=True),
                     self.pmc_profile_path)
        atomic_write(self.scav.json(exclude_defaults=True),
                     self.scav_profile_path)

    def update(self) -> None:
        self.hideout.update()

    def __enter__(self) -> Profile:
        self.read()
        return self

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        if exc_type is None:
            self.write()