def generate(self, bot_role: str) -> dict: """ Generates bot profile with role specified in class constructor. All bot parameters such as inventory and health are taken from database. :return: Bot profile as dictionary """ preset: BotGeneratorPreset = self.preset_factory(bot_role=bot_role) bot_inventory = BotInventory.make_empty() bot_base = copy.deepcopy(self._bot_base) with bot_inventory: equipment_generator = BotEquipmentGenerator( bot_inventory=bot_inventory, preset=preset) equipment_generator.generate_equipment() weapon_generator = BotWeaponGenerator(bot_inventory=bot_inventory, preset=preset) weapon_generator.generate() loot_generator = BotLootGenerator(bot_inventory=bot_inventory, preset=preset) loot_generator.generate() bot_inventory.regenerate_ids() bot_base["Inventory"] = bot_inventory.inventory.dict(exclude_none=True) bot_base["Health"] = copy.deepcopy(preset.health) bot_base["_id"] = generate_item_id() bot_base["Info"]["Side"] = "Savage" self.__generate_appearance(bot_base, preset) return bot_base
def __generate_mod(self, slot: str, template_ids: List[TemplateId], parent: Item) -> None: try: if not random.uniform(0, 100) <= self.preset.chances["mods"][slot]: return except KeyError: return template_ids = list( filter(self.__filter_conflicting_items, template_ids)) if not template_ids: return random_template = self.templates_repository.get_template( random.choice(template_ids)) # Ammo generation will be handler later via BotMagazineGenerator class if slot == "cartridges": return item = Item( id=generate_item_id(), tpl=random_template.id, slot_id=slot, parent_id=parent.id, ) self.bot_inventory.add_item(item)
def _generate_offer( self, item_template: ItemTemplate, ) -> Offer: """ Generates single offer """ offer_items: List[Item] offer_price: int root_item: Item sell_in_one_piece = False if self.__globals_repository.has_preset(item_template): preset = self.__globals_repository.item_preset(item_template) root_item, children = preset.get_items() offer_items = [root_item, *children] sell_in_one_piece = True elif isinstance(item_template.props, AmmoProps): ammo_count = int( random.gauss( item_template.props.StackMaxSize * 0.75, item_template.props.StackMaxSize * 1.25, )) ammo_count = max(1, abs(ammo_count)) root_item, _ = self.__item_factory.create_item(item_template, 1) offer_items = [root_item] root_item.upd.StackObjectsCount = ammo_count else: root_item, child_items = self.__item_factory.create_item( item_template) offer_items = [root_item, *child_items] offer_price = sum(self.item_prices[i.tpl] for i in offer_items) offer_price = int(random.gauss(offer_price * 1.1, offer_price * 0.1)) requirement = OfferRequirement( template_id=TemplateId("5449016a4bdc2d6f028b456f"), count=offer_price, ) now = datetime.now() expiration_time = random.gauss( timedelta(hours=6).total_seconds(), timedelta(hours=6).total_seconds()) expires_at = now + timedelta(seconds=abs(expiration_time)) return Offer( id=OfferId(generate_item_id()), intId=random.randint(0, 999_999), user=self._make_random_user(), root=root_item.id, items=offer_items, itemsCost=offer_price, requirements=[requirement], requirementsCost=offer_price, summaryCost=offer_price, sellInOnePiece=sell_in_one_piece, startTime=0, endTime=int(expires_at.timestamp()), )
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)
def _make_random_user(self) -> FleaUser: return FleaUser( id=generate_item_id(), nickname=self.__get_random_username(), avatar="/files/trader/avatar/unknown.jpg", memberType=0, rating=0.0, isRatingGrowing=True, )
def make_empty() -> BotInventory: equipment_id = generate_item_id() stash_id = generate_item_id() quest_raid_items_id = generate_item_id() quest_stash_items_id = generate_item_id() bot_inventory = { "items": [ { "_id": stash_id, "_tpl": "566abbc34bdc2d92178b4576" }, { "_id": quest_raid_items_id, "_tpl": "5963866286f7747bf429b572" }, { "_id": quest_stash_items_id, "_tpl": "5963866b86f7747bfa1c4462" }, { "_id": equipment_id, "_tpl": "55d7217a4bdc2d86028b456d" }, ], "equipment": equipment_id, "stash": stash_id, "questRaidItems": quest_raid_items_id, "questStashItems": quest_stash_items_id, "fastPanel": {}, } return BotInventory(bot_inventory)
def create_item( self, item_template: ItemTemplate, count: int = 1, ) -> Tuple[Item, List[Item]]: try: return self.globals_repository.item_preset( item_template).get_items() except NotFoundError: pass item = Item( id=generate_item_id(), tpl=item_template.id, ) if isinstance(item_template.props, AmmoBoxProps): ammo_template_id: TemplateId = item_template.props.StackSlots[0][ "_props"]["filters"][0]["Filter"][0] ammo_template = self.templates_repository.get_template( ammo_template_id) ammo, _ = self.create_item(ammo_template, 1) ammo.upd.StackObjectsCount = count ammo.parent_id = item.id ammo.slot_id = "cartridges" return item, [ammo] if count > item_template.props.StackMaxSize: raise ValueError( f"Trying to create item with template id {item_template} with stack size " f"of {count} but maximum stack size is {item_template.props.StackMaxSize}" ) if count > 1: item.upd.StackObjectsCount = count # Item is either medkit or a painkiller if isinstance(item_template.props, MedsProps): medkit_max_hp = item_template.props.MaxHpResource item.upd.MedKit = ItemUpdMedKit(HpResource=medkit_max_hp) if isinstance(item_template.props, FuelProps): item.upd.Resource = ItemUpdResource( Value=item_template.props.MaxResource) item.parent_id = None return item, []
def create_account(self, email: str, password: str, edition: str) -> Account: for account in self.accounts: if account.email == email: raise ValueError(f"Account with email {email} already exists") account = Account( id=generate_item_id(), email=email, password=password, edition=edition, nickname="", ) self.accounts.append(account) self.__write() return account
def from_items(items: List[Item]) -> MailMessageItems: """ Creates MailMessageItems from list of items """ stash_id = generate_item_id() for item in items: if not item.parent_id: item.parent_id = stash_id if not item.slot_id: item.slot_id = "main" regenerate_items_ids(items) return MailMessageItems( stash=stash_id, data=items, )
def from_items(cls, items: List[Item]) -> MailMessageItems: """ Creates MailMessageItems from list of items """ # We have to remove parent_id and slot_id # from items that have no parent in this list of items. items = clean_items_relationships(items) stash_id = generate_item_id() for item in items: if not item.parent_id: item.parent_id = stash_id if not item.slot_id: item.slot_id = "main" item.location = None regenerate_items_ids(items) return cls( stash=stash_id, data=items, )
def generate_equipment(self) -> None: """ Generates equipment items (Weapons, Backpack, Rig, etc) """ # A set with equipment slots that should be generated equipment_slots_to_generate: Set[str] = { slot for slot, template_ids in self.preset.inventory["equipment"].items() if ( # If slot isn't present in the _chances then it should be always generated slot not in self.preset.chances["equipment"] # Else we check if it should spawn or random.uniform(0, 100) <= self.preset.chances["equipment"] [slot]) and template_ids } # Force pistol to generate if primary weapon wasn't generated weapon_slots = "FirstPrimaryWeapon", "SecondPrimaryWeapon" if not any(slot in equipment_slots_to_generate for slot in weapon_slots): equipment_slots_to_generate.add("Holster") assert any(i in weapon_slots for i in ("FirstPrimaryWeapon", "SecondPrimaryWeapon", "Holster")) for equipment_slot in equipment_slots_to_generate: template_ids = self.preset.inventory["equipment"][equipment_slot] template_ids = [ i for i in template_ids if self.__filter_conflicting_items( i, equipment_slots_to_generate) ] random_template_id = random.choice(template_ids) self.bot_inventory.add_item( Item( id=generate_item_id(), tpl=random_template_id, slot_id=equipment_slot, parent_id=self.bot_inventory.inventory.equipment, ))