def check_better_artifact_power(self, distribution): median_power = Power.power_to_artifact(distribution, 100) for i in range(100): power = Power.better_artifact_power_randomized(distribution, 100) self.assertTrue(median_power.physic < power.physic) self.assertTrue(median_power.magic < power.magic)
def test_sharp__no_choices__and_force(self): artifact = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) artifact.sharp(distribution=PowerDistribution(0.5, 0.5), max_power=Power(1, 1), force=True) self.assertEqual(artifact.power.total(), 3)
def test_damage_integrity__damage_from_artifact_power(self): expected_artifact_power = Power.normal_power_to_level(self.hero.level) new_artifact = artifacts_storage.artifacts.generate_artifact_from_list( artifacts_storage.artifacts.artifacts, self.hero.level, rarity=artifacts_relations.RARITY.NORMAL) new_artifact.power = Power(expected_artifact_power / 2, expected_artifact_power / 2) self.hero.equipment.unequip(new_artifact.type.equipment_slot) self.hero.equipment.equip(new_artifact.type.equipment_slot, new_artifact) old_integrity = new_artifact.integrity self.hero.damage_integrity() not_modified_integrity = new_artifact.integrity new_artifact.power = Power(expected_artifact_power, expected_artifact_power) self.hero.damage_integrity() modified_integrity = new_artifact.integrity self.assertTrue( old_integrity - not_modified_integrity < not_modified_integrity - modified_integrity)
def dress_new_hero(hero): hero.equipment.equip( EQUIPMENT_SLOT.PANTS, artifacts_storage.get_by_uuid( DEFAULT_HERO_EQUIPMENT.PANTS).create_artifact(level=1, power=Power(1, 1))) hero.equipment.equip( EQUIPMENT_SLOT.BOOTS, artifacts_storage.get_by_uuid( DEFAULT_HERO_EQUIPMENT.BOOTS).create_artifact(level=1, power=Power(1, 1))) hero.equipment.equip( EQUIPMENT_SLOT.PLATE, artifacts_storage.get_by_uuid( DEFAULT_HERO_EQUIPMENT.PLATE).create_artifact(level=1, power=Power(1, 1))) hero.equipment.equip( EQUIPMENT_SLOT.GLOVES, artifacts_storage.get_by_uuid( DEFAULT_HERO_EQUIPMENT.GLOVES).create_artifact(level=1, power=Power(1, 1))) hero.equipment.equip( EQUIPMENT_SLOT.HAND_PRIMARY, artifacts_storage.get_by_uuid( DEFAULT_HERO_EQUIPMENT.WEAPON).create_artifact(level=1, power=Power(1, 1)))
def test_drop_cheapest_item(self): artifact_1 = artifacts_storage.artifacts.generate_artifact_from_list( artifacts_storage.artifacts.artifacts, self.hero.level, rarity=artifacts_relations.RARITY.NORMAL) artifact_2 = artifacts_storage.artifacts.generate_artifact_from_list( artifacts_storage.artifacts.artifacts, self.hero.level, rarity=artifacts_relations.RARITY.NORMAL) artifact_1.power = Power(200, 200) artifact_2.power = Power(1, 1) self.hero.bag.put_artifact(artifact_1) self.hero.bag.put_artifact(artifact_2) distribution = self.hero.preferences.archetype.power_distribution self.assertEqual(self.hero.bag.occupation, 2) dropped_item = self.hero.bag.drop_cheapest_item(distribution) self.assertEqual(self.hero.bag.occupation, 1) self.assertEqual(dropped_item.id, artifact_2.id) self.assertEqual(list(self.hero.bag.values())[0].id, artifact_1.id)
def test_only_better_for_prefered_slot(self): self.hero.level = 9999 self.hero.preferences.set(relations.PREFERENCE_TYPE.EQUIPMENT_SLOT, relations.EQUIPMENT_SLOT.PLATE) # just set any artifact self.hero.receive_artifact(equip=True, better=False, prefered_slot=True, prefered_item=True, archetype=True) distribution = self.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval( distribution, self.hero.level) for i in range(100): old_artifact = self.hero.equipment.get( relations.EQUIPMENT_SLOT.PLATE) old_artifact.power = max_power - Power(1, 1) self.hero.receive_artifact(equip=True, better=True, prefered_slot=True, prefered_item=True, archetype=True) self.assertTrue( self.hero.equipment.get(relations.EQUIPMENT_SLOT.PLATE ).preference_rating(distribution) > old_artifact.preference_rating(distribution))
def check_better_artifact_power(self, distribution): median_power = Power.power_to_artifact(distribution, 100) for i in xrange(100): power = Power.better_artifact_power_randomized(distribution, 100) self.assertTrue(median_power.physic < power.physic) self.assertTrue(median_power.magic < power.magic)
def test_sharp__magic(self): artifact = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) artifact.sharp(distribution=PowerDistribution(0.0, 1.0), max_power=Power(3, 3)) artifact.sharp(distribution=PowerDistribution(0.0, 1.0), max_power=Power(3, 3)) self.assertEqual(artifact.power, Power(1, 3))
def test_sharp__both(self): artifact = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) artifact.sharp(distribution=PowerDistribution(0.5, 0.5), max_power=Power(2, 2)) artifact.sharp(distribution=PowerDistribution(0.5, 0.5), max_power=Power(2, 2)) self.assertEqual(artifact.power, Power(2, 2))
def test_sharp_artifact(self): old_power = self.hero.power artifact = self.hero.sharp_artifact() self.assertTrue(self.hero.power.physic > old_power.physic or self.hero.power.magic > old_power.magic) self.assertTrue(artifact.power == Power(2, 1) or artifact.power == Power(1, 2)) self.assertTrue(self.hero.equipment.updated)
def test_put_loot__bonus_power_for_artifact(self): artifact = artifacts_storage.artifacts.generate_artifact_from_list( artifacts_storage.artifacts.artifacts, self.hero.level, rarity=artifacts_relations.RARITY.NORMAL) artifact.power = Power(0, 0) self.hero.put_loot(artifact) self.assertEqual(artifact.power, Power(1, 1))
def test_preference_rating__rarity(self): self.assertTrue( ArtifactPrototype._preference_rating( relations.RARITY.NORMAL, Power(100, 100), PowerDistribution(0.5, 0.5)) < ArtifactPrototype. _preference_rating(relations.RARITY.RARE, Power( 100, 100), PowerDistribution(0.5, 0.5)) < ArtifactPrototype. _preference_rating(relations.RARITY.EPIC, Power(100, 100), PowerDistribution(0.5, 0.5)))
def test_make_better_than__magic(self): artifact_1 = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) artifact_2 = self.artifact_record.create_artifact(level=1, power=Power(3, 3)) artifact_1.make_better_than(artifact_2, PowerDistribution(0, 1.0)) self.assertTrue(artifact_1.power.magic > 3) self.assertEqual(artifact_1.power.physic, 1)
def test_corridor(self): # fill_empty_keys_with_fake_phrases(u'test_hero_level_companion') result, account_id, bundle_id = register_user(uuid.uuid4().hex) # pylint: disable=W0612 self.storage = LogicStorage() self.storage.load_account_data(AccountPrototype.get_by_id(account_id)) self.hero = self.storage.accounts_to_heroes[account_id] self.set_hero_companion() current_time = TimePrototype.get_current_time() for level in xrange(1, 100): print print '-----------------------------------------------------------------------' print 'process level %d\texpected turns: %d\texpected days: %.2f' % (level, f.turns_on_lvl(level), f.time_on_lvl(level)/24) for i in xrange(f.turns_on_lvl(level)): # pylint: disable=W0612 self.storage.process_turn() current_time.increment_turn() # simulate user behaviour on healing companion if self.hero.companion.health < self.hero.companion.max_health / 2: self.hero.companion.health = self.hero.companion.max_health self.hero.randomized_level_up() exp_to_next_level = float(self.hero.experience) / f.exp_on_lvl(self.hero.level) * 100 exp_from_expected = float(f.total_exp_to_lvl(self.hero.level)+self.hero.experience)/f.total_exp_to_lvl(level+1)*100 exp_untaken = f.total_exp_to_lvl(level+1) - f.total_exp_to_lvl(self.hero.level) - self.hero.experience quests_untaken = float(exp_untaken) / f.experience_for_quest(c.QUEST_AREA_RADIUS) print u'hero level: %d\texp: %.2f%%\texp from expected: %.2f%% (%d exp, %.2f quests)\ttotal quests %d' % (self.hero.level, exp_to_next_level, exp_from_expected, exp_untaken, quests_untaken, self.hero.statistics.quests_done) print u'abilities: %s' % ' '.join(u'%s-%d' % (ability_id, ability.level) for ability_id, ability in self.hero.abilities.abilities.items()) print u'deaths: %d' % self.hero.statistics.pve_deaths total_gold = f.total_gold_at_lvl(self.hero.level) print u'total money: %d from expected %d (x%.2f)' % (self.hero.statistics.money_earned, total_gold, float(self.hero.statistics.money_earned) / total_gold if total_gold > 0 else 0) total_artifacts = int(f.total_time_for_lvl(self.hero.level) / 24 * c.ARTIFACTS_LOOT_PER_DAY ) print u'total artifacts: %d from expected %d (x%.2f)' % (self.hero.statistics.artifacts_had, total_artifacts, float(self.hero.statistics.artifacts_had) / total_artifacts if total_artifacts > 0 else 0) print u'power: %r from expected %r' % (self.hero.power, Power.power_to_level(self.hero.preferences.archetype.power_distribution, self.hero.level)) print u'power total: %d from expected %r (x%.2f)' % (self.hero.power.total(), Power.power_to_level(self.hero.preferences.archetype.power_distribution, self.hero.level).total(), float(self.hero.power.total()) / Power.power_to_level(self.hero.preferences.archetype.power_distribution, self.hero.level).total())
def test_compare_drop__artifact_and_artifact(self): artifact_1 = artifacts_storage.generate_artifact_from_list(artifacts_storage.artifacts, 1, rarity=artifacts_relations.RARITY.NORMAL) artifact_2 = artifacts_storage.generate_artifact_from_list(artifacts_storage.artifacts, 1, rarity=artifacts_relations.RARITY.NORMAL) artifact_2.power = Power(1, 1) artifact_1.power = Power(2, 2) distribution = self.hero.preferences.archetype.power_distribution self.assertTrue(self.hero.bag._compare_drop(distribution, artifact_1, artifact_2)) self.assertFalse(self.hero.bag._compare_drop(distribution, artifact_2, artifact_1))
def test_process_artifact_breaking__break_only_mostly_damaged(self): for artifact in self.hero.equipment.values(): artifact.power = Power(100, 100) artifact.integrity = 0 artifact.integrity = artifact.max_integrity for i in xrange(100): self.action_battle.process_artifact_breaking() self.assertEqual(artifact.power, Power(100, 100))
def test_make_better_than__already_better(self): artifact_1 = self.artifact_record.create_artifact(level=1, power=Power(2, 2)) artifact_2 = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) old_power = artifact_1.power.clone() artifact_1.make_better_than(artifact_2, PowerDistribution(0.5, 0.5)) self.assertEqual(artifact_1.power, old_power)
def test_break_it__large_integrity(self): artifact = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) old_max_integrity = artifact.max_integrity artifact.break_it() self.assertEqual(artifact.power, Power(1, 1)) self.assertTrue(old_max_integrity > artifact.max_integrity) self.assertEqual(artifact.integrity, artifact.max_integrity)
def test_make_better_than__both(self): artifact_1 = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) artifact_2 = self.artifact_record.create_artifact(level=1, power=Power( 100, 100)) artifact_1.make_better_than(artifact_2, PowerDistribution(0.5, 0.5)) self.assertTrue(artifact_1.power.physic > 100 or artifact_1.power.magic > 100)
def test_sharp_artifact(self): old_power = self.hero.power with mock.patch('the_tale.game.heroes.bag.Equipment.mark_updated') as mark_updated: artifact = self.hero.sharp_artifact() self.assertTrue(mark_updated.call_count >= 1) self.assertTrue(self.hero.power.physic > old_power.physic or self.hero.power.magic > old_power.magic) self.assertTrue(artifact.power == Power(2, 1) or artifact.power == Power(1, 2))
def test_sharp__no_choices(self): artifact = self.artifact_record.create_artifact(level=1, power=Power(1, 1)) old_integrity = artifact.integrity old_max_integrity = artifact.max_integrity artifact.sharp(distribution=PowerDistribution(0.5, 0.5), max_power=Power(1, 1)) self.assertEqual(artifact.power, Power(1, 1)) self.assertEqual(old_integrity, artifact.integrity) self.assertEqual(old_max_integrity, artifact.max_integrity)
def test_better_artifact_power__on_low_levels(self): median_power = Power.power_to_artifact(PowerDistribution(0.5, 0.5), 1) self.assertEqual(median_power, Power(1, 1)) powers = set() for i in range(100): power = Power.better_artifact_power_randomized(PowerDistribution(0.5, 0.5), 1) powers.add(power.magic) powers.add(power.physic) self.assertEqual(1 + c.ARTIFACT_BETTER_MIN_POWER_DELTA*2, len(powers))
def test_better_artifact_power__on_low_levels(self): median_power = Power.power_to_artifact(PowerDistribution(0.5, 0.5), 1) self.assertEqual(median_power, Power(1, 1)) powers = set() for i in range(100): power = Power.better_artifact_power_randomized(PowerDistribution(0.5, 0.5), 1) powers.add(power.magic) powers.add(power.physic) self.assertEqual(1 + c.ARTIFACT_BETTER_MIN_POWER_DELTA * 2, len(powers))
def get_power(self): power = Power(0, 0) for slot in EQUIPMENT_SLOT.records: artifact = self._get(slot) if artifact: power += artifact.power return power
def sharp_artifact(self): choices = list(relations.EQUIPMENT_SLOT.records) random.shuffle(choices) if self.preferences.equipment_slot is not None and self.can_upgrade_prefered_slot: choices.insert(0, self.preferences.equipment_slot) distribution = self.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval( distribution, self.level) # pylint: disable=W0612 for slot in choices: artifact = self.equipment.get(slot) if artifact is not None and artifact.sharp(distribution, max_power): self.equipment.updated = True return artifact # if all artifacts are on maximum level random.shuffle(choices) for slot in choices: artifact = self.equipment.get(slot) if artifact is not None and artifact.sharp( distribution, max_power, force=True): self.equipment.updated = True return artifact
def receive_artifacts_slots_choices(self, better, prefered_slot, prefered_item): from the_tale.game.artifacts.prototypes import ArtifactPrototype allowed_slots = list(relations.EQUIPMENT_SLOT.records) slot_choices = list(allowed_slots) if prefered_slot and self.preferences.equipment_slot and self.can_upgrade_prefered_slot: slot_choices = [self.preferences.equipment_slot] if prefered_item and self.preferences.favorite_item and self.preferences.favorite_item in slot_choices: #after prefered slot, since prefered item is more important slot_choices.remove(self.preferences.favorite_item) result_choices = [] if better: for slot in slot_choices: artifact = self.equipment.get(slot) if artifact is not None: distribution = self.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, self.level) # pylint: disable=W0612 if artifact.preference_rating(distribution) >= ArtifactPrototype._preference_rating(artifact.rarity, max_power, distribution): continue result_choices.append(slot) else: result_choices = slot_choices return result_choices
def test_process_artifact_breaking__not_broken(self): for artifact in self.hero.equipment.values(): artifact.power = Power(100, 100) old_power = self.hero.power.total() self.action_battle.process_artifact_breaking() self.assertEqual(old_power, self.hero.power.total())
def test_get_equip_candidates__ignore_favorite_item_slot(self): self.assertTrue(self.hero.bag.is_empty) self.assertTrue( self.hero.equipment.get(relations.EQUIPMENT_SLOT.HAND_PRIMARY)) self.assertEqual(self.hero.preferences.favorite_item, None) old_artifact = self.hero.equipment.get( relations.EQUIPMENT_SLOT.HAND_PRIMARY) artifact = artifacts_storage.artifacts.generate_artifact_from_list( artifacts_storage.artifacts.artifacts_for_type( [relations.EQUIPMENT_SLOT.HAND_PRIMARY.artifact_type]), self.hero.level, rarity=artifacts_relations.RARITY.NORMAL) artifact.power = old_artifact.power + Power(1, 1) self.hero.bag.put_artifact(artifact) slot, unequipped, equipped = self.hero.get_equip_candidates() self.assertEqual(slot, relations.EQUIPMENT_SLOT.HAND_PRIMARY) self.assertEqual(unequipped, old_artifact) self.assertEqual(equipped, artifact) self.hero.preferences.set(relations.PREFERENCE_TYPE.FAVORITE_ITEM, relations.EQUIPMENT_SLOT.HAND_PRIMARY) slot, unequipped, equipped = self.hero.get_equip_candidates() self.assertEqual(slot, None) self.assertEqual(unequipped, None) self.assertEqual(equipped, None)
def test_purchase_artifact__not_better_artifact__large_level(self): self.hero.level = 100 self.assertEqual(self.hero.level, 100) rarity = RARITY.NORMAL distribution = self.hero.preferences.archetype.power_distribution middle_power = Power.power_to_artifact(distribution, self.hero.level) N = 100 results = set() with mock.patch( 'the_tale.game.actions.container.ActionsContainer.request_replane' ) as request_replane: for i in xrange(N): results.add( self.hero.purchase_artifact( rarity=RARITY.NORMAL, better=False).preference_rating( distribution) > ArtifactPrototype. _preference_rating(rarity, middle_power, distribution)) self.assertEqual(results, set([True, False])) self.assertEqual(request_replane.call_count, N)
def test_sharp_artifact_when_all_artifacts_has_max_power(self): distribution = self.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, self.hero.level) for artifact in self.hero.equipment.equipment.values(): artifact.power = max_power.clone() old_power = self.hero.power artifact = self.hero.sharp_artifact() self.assertTrue(self.hero.power.physic > old_power.physic or self.hero.power.magic > old_power.magic) self.assertTrue(artifact.power == max_power + Power(1, 0) or artifact.power == max_power + Power(0, 1)) self.assertTrue(self.hero.equipment.updated)
def break_it(self): self.power = Power( physic=max( 1, int(self.power.physic * (1 - random.uniform(*c.ARTIFACT_BREAK_POWER_FRACTIONS)) - 1)), magic=max( 1, int(self.power.magic * (1 - random.uniform(*c.ARTIFACT_BREAK_POWER_FRACTIONS)) - 1))) self.max_integrity = int( self.max_integrity * (1 - random.uniform(*c.ARTIFACT_BREAK_INTEGRITY_FRACTIONS))) self.integrity = min(self.integrity, self.max_integrity)
def purchase_artifact(self, rarity, better): distribution = self.preferences.archetype.power_distribution power = Power.better_artifact_power_randomized( distribution, self.level) if better else Power.artifact_power_randomized( distribution, self.level) artifacts_storage.sync() artifact = random.choice(artifacts_storage.artifacts).create_artifact( level=self.level, power=power, rarity=rarity) self.put_loot(artifact, force=True) self.actions.request_replane() return artifact
class SpecialAura(BaseEffect): TYPE = relations.ARTIFACT_EFFECT.SPECIAL_AURA DESCRIPTION = u'Физическая и магическая сила всех артефактов, получаемых героем, увеличивается на 1' MULTIPLIER = Power(1, 1) @classmethod def modify_attribute(cls, type_, value): return value + cls.MULTIPLIER if type_.is_BONUS_ARTIFACT_POWER else value
def break_it(self): self.power = Power( physic=max(1, int(self.power.physic * (1 - random.uniform(*c.ARTIFACT_BREAK_POWER_FRACTIONS)) - 1)), magic=max(1, int(self.power.magic * (1 - random.uniform(*c.ARTIFACT_BREAK_POWER_FRACTIONS)) - 1)), ) self.max_integrity = int(self.max_integrity * (1 - random.uniform(*c.ARTIFACT_BREAK_INTEGRITY_FRACTIONS))) self.integrity = min(self.integrity, self.max_integrity)
def test_receive_artifacts_slots_choices__better_false(self): distribution = self.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, self.hero.level) # pylint: disable=W0612 for artifact in self.hero.equipment.values(): artifact.power = max_power self.assertEqual(set(self.hero.receive_artifacts_slots_choices(better=False, prefered_slot=False, prefered_item=False)), set(relations.EQUIPMENT_SLOT.records))
def use(self, task, storage, **kwargs): # pylint: disable=R0911,W0613 for artifact in task.hero.equipment.values(): distribution = task.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, task.hero.level) artifact.sharp(distribution=distribution, max_power=max_power, force=True) return task.logic_result(message=u"Вся экипировка героя улучшена")
def test_purchase_artifact__better_artifact__min_level(self): self.assertEqual(self.hero.level, 1) rarity = RARITY.NORMAL distribution = self.hero.preferences.archetype.power_distribution middle_power = Power.power_to_artifact(distribution, self.hero.level) for i in xrange(100): self.assertTrue(self.hero.purchase_artifact(rarity=RARITY.NORMAL, better=True).preference_rating(distribution) > ArtifactPrototype._preference_rating(rarity, middle_power, distribution))
def test_sharp_preferences_with_max_power(self): distribution = self.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, self.hero.level) self.hero.preferences.set_equipment_slot(relations.EQUIPMENT_SLOT.HAND_PRIMARY) artifact = self.hero.equipment.get(relations.EQUIPMENT_SLOT.HAND_PRIMARY) artifact.power = max_power artifact = self.hero.sharp_artifact() self.assertFalse(artifact.type.is_MAIN_HAND)
def use(self, task, storage, **kwargs): # pylint: disable=R0911,W0613 artifact = random.choice(task.hero.equipment.values()) distribution=task.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, task.hero.level) artifact.sharp(distribution=distribution, max_power=max_power, force=True) return task.logic_result(message=u'Улучшена экипировка героя: %(artifact)s' % {'artifact': artifact.html_label()})
def damage_integrity(self): if random.random() < self.safe_artifact_integrity_probability: return expected_artifact_power = Power.normal_power_to_level(self.level) for artifact in self.equipment.values(): delta = c.ARTIFACT_INTEGRITY_DAMAGE_PER_BATTLE * (float(artifact.power.total()) / expected_artifact_power)**2 if self.preferences.favorite_item is not None and self.preferences.favorite_item == artifact.type.equipment_slot: delta *= c.ARTIFACT_INTEGRITY_DAMAGE_FOR_FAVORITE_ITEM artifact.damage_integrity(delta)
def purchase_artifact(self, rarity, better): distribution = self.preferences.archetype.power_distribution power = Power.better_artifact_power_randomized(distribution, self.level) if better else Power.artifact_power_randomized(distribution, self.level) artifacts_storage.sync() artifact = random.choice(artifacts_storage.artifacts).create_artifact(level=self.level, power=power, rarity=rarity) self.put_loot(artifact, force=True) self.actions.request_replane() return artifact
def test_only_better_for_prefered_slot(self): self.hero._model.level = 9999 self.hero.preferences.set_equipment_slot(relations.EQUIPMENT_SLOT.PLATE) # just set any artifact self.hero.receive_artifact(equip=True, better=False, prefered_slot=True, prefered_item=True, archetype=True) distribution = self.hero.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, self.hero.level) for i in xrange(100): old_artifact = self.hero.equipment.get(relations.EQUIPMENT_SLOT.PLATE) old_artifact.power = max_power - Power(1, 1) self.hero.receive_artifact(equip=True, better=True, prefered_slot=True, prefered_item=True, archetype=True) self.assertTrue(self.hero.equipment.get(relations.EQUIPMENT_SLOT.PLATE).preference_rating(distribution) > old_artifact.preference_rating(distribution))
def test_purchase_artifact__better_artifact__large_level(self): self.hero.level = 100 self.assertEqual(self.hero.level, 100) rarity = RARITY.NORMAL distribution = self.hero.preferences.archetype.power_distribution middle_power = Power.power_to_artifact(distribution, self.hero.level) N = 100 with mock.patch('the_tale.game.actions.container.ActionsContainer.request_replane') as request_replane: for i in xrange(N): self.assertTrue(self.hero.purchase_artifact(rarity=RARITY.NORMAL, better=True).preference_rating(distribution) > ArtifactPrototype._preference_rating(rarity, middle_power, distribution)) self.assertEqual(request_replane.call_count, N)
def deserialize(cls, data): # if artifact record is desabled or deleted, get another random record from the_tale.game.artifacts.storage import artifacts_storage record = artifacts_storage.get_by_uuid(data['id']) if record is None or record.state.is_DISABLED: record = random.choice(artifacts_storage.artifacts) integrity = data.get('integrity', [c.ARTIFACT_MAX_INTEGRITY, c.ARTIFACT_MAX_INTEGRITY]) return cls(record_id=record.id, power=Power.deserialize(data['power']), bag_uuid=data['bag_uuid'], integrity=integrity[0], max_integrity=integrity[1], rarity=relations.RARITY.index_value[data.get('rarity', relations.RARITY.NORMAL.value)], level=data.get('level', 1))
def get_battles_statistics(hero_1, hero_2): hero_1_wins = 0 hero_2_wins = 0 for hero_level in HERO_LEVELS: with mock.patch('the_tale.game.heroes.objects.Hero.power', Power.power_to_level(POWER_DISTRIBUTION, hero_level)): hero_1._model.level = hero_level hero_2._model.level = hero_level for i in xrange(TEST_BATTLES_NUMBER): # pylint: disable=W0612 hero_1.health = hero_1.max_health hero_2.health = hero_2.max_health if process_battle(hero_1, hero_2): hero_1_wins += 1 else: hero_2_wins += 1 return hero_1_wins, hero_2_wins
def test_damage_integrity__damage_from_artifact_power(self): expected_artifact_power = Power.normal_power_to_level(self.hero.level) new_artifact = artifacts_storage.generate_artifact_from_list(artifacts_storage.artifacts, self.hero.level, rarity=artifacts_relations.RARITY.NORMAL) new_artifact.power = Power(expected_artifact_power / 2, expected_artifact_power / 2) self.hero.equipment.unequip(new_artifact.type.equipment_slot) self.hero.equipment.equip(new_artifact.type.equipment_slot, new_artifact) old_integrity = new_artifact.integrity self.hero.damage_integrity() not_modified_integrity = new_artifact.integrity new_artifact.power = Power(expected_artifact_power, expected_artifact_power) self.hero.damage_integrity() modified_integrity = new_artifact.integrity self.assertTrue(old_integrity - not_modified_integrity < not_modified_integrity - modified_integrity)
def generate_artifact_from_list(self, artifacts_list, level, rarity): artifact_choices = [] for artifact_record in artifacts_list: if artifact_record.state.is_ENABLED and artifact_record.accepted_for_level(level): artifact_choices.append(artifact_record) if not artifact_choices: return None artifact_record = random.choice(artifact_choices) if artifact_record.is_useless: power = Power(0, 0) else: power = Power.artifact_power_randomized(distribution=artifact_record.power_type.distribution, level=level) return artifact_record.create_artifact(level=level, power=power, rarity=rarity)
def sharp_artifact(self): choices = list(relations.EQUIPMENT_SLOT.records) random.shuffle(choices) if self.preferences.equipment_slot is not None and self.can_upgrade_prefered_slot: choices.insert(0, self.preferences.equipment_slot) distribution = self.preferences.archetype.power_distribution min_power, max_power = Power.artifact_power_interval(distribution, self.level) # pylint: disable=W0612 for slot in choices: artifact = self.equipment.get(slot) if artifact is not None and artifact.sharp(distribution, max_power): self.equipment.updated = True return artifact # if all artifacts are on maximum level random.shuffle(choices) for slot in choices: artifact = self.equipment.get(slot) if artifact is not None and artifact.sharp(distribution, max_power, force=True): self.equipment.updated = True return artifact
def show_balance(self): # pylint: disable=R0914 tmp_time = [ u"начало", u"8 часов", u"день", u"неделя", u"месяц", u"3 месяца", u"6 месяцев", u"1 год", u"2 года", u"3 года", u"4 года", u"5 лет", u"6 лет", ] tmp_times = [ 0, 8, 24, 24 * 7, 24 * 30, 24 * 30 * 3, 24 * 30 * 6, 24 * 30 * 12, 24 * 30 * 12 * 2, 24 * 30 * 12 * 3, 24 * 30 * 12 * 4, 24 * 30 * 12 * 5, 24 * 30 * 12 * 6, ] tmp_lvls = map(f.lvl_after_time, tmp_times) # Всё, что ниже, должно зависеть от уровня, не от времени, т.к. время в данном случае не точный параметр, а анализ всё равно ориентируется на уровень. exp_for_quest = f.experience_for_quest__real(c.QUEST_AREA_RADIUS) tmp_exp_to_level = map(math.floor, map(f.exp_on_lvl, tmp_lvls)) tmp_exp_total = map(math.floor, map(f.total_exp_to_lvl, tmp_lvls)) tmp_quests_to_level = map(math.ceil, (exp / float(exp_for_quest) for exp in tmp_exp_to_level)) tmp_quests_total = map(math.ceil, (exp / float(exp_for_quest) for exp in tmp_exp_total)) dstr = PowerDistribution(0.5, 0.5) tmp_hp = map(f.hp_on_lvl, tmp_lvls) tmp_turns = map(f.turns_on_lvl, tmp_lvls) tmp_turns_to_time = map(int, map(f.hours_to_turns, tmp_times)) tmp_expected_damage_to_hero_per_hit = map(f.expected_damage_to_hero_per_hit, tmp_lvls) tmp_expected_damage_to_hero_per_hit_interval = [ (int(round(dmg * (1 - c.DAMAGE_DELTA))), int(round(dmg * (1 + c.DAMAGE_DELTA)))) for dmg in tmp_expected_damage_to_hero_per_hit ] tmp_mob_hp = map(f.mob_hp_to_lvl, tmp_lvls) tmp_power = map(lambda lvl: Power.power_to_level(dstr, lvl), tmp_lvls) tmp_expected_damage_to_mob_per_hit = map(f.expected_damage_to_mob_per_hit, tmp_lvls) tmp_real_damage_to_mob_per_hit = map(lambda p: p.damage().total, tmp_power) tmp_real_damage_to_mob_per_hit_interval = [ (int(round(dmg * (1 - c.DAMAGE_DELTA))), int(round(dmg * (1 + c.DAMAGE_DELTA)))) for dmg in tmp_real_damage_to_mob_per_hit ] tmp_power_per_slot = [Power.power_to_artifact(dstr, lvl) for lvl in tmp_lvls] tmp_battles_at_lvl = map(math.floor, [x * c.BATTLES_PER_HOUR for x in map(f.time_on_lvl, tmp_lvls)]) tmp_total_battles = map(math.floor, [x * c.BATTLES_PER_HOUR for x in map(f.total_time_for_lvl, tmp_lvls)]) tmp_artifacts_per_battle = [c.ARTIFACTS_PER_BATTLE] * len(tmp_lvls) tmp_artifacts_total = [c.ARTIFACTS_LOOT_PER_DAY * f.total_time_for_lvl(lvl - 1) / 24.0 for lvl in tmp_lvls] tmp_gold_in_day = map(f.expected_gold_in_day, tmp_lvls) tmp_total_gold_at_lvl = map(f.total_gold_at_lvl, tmp_lvls) return self.template( "balance/balance.html", { "c": c, "f": f, "exp_for_quest": exp_for_quest, "average_path_length": c.QUEST_AREA_RADIUS, "tmp_time": tmp_time, "tmp_lvls": tmp_lvls, "tmp_exp_to_level": tmp_exp_to_level, "tmp_exp_total": tmp_exp_total, "tmp_quests_to_level": tmp_quests_to_level, "tmp_quests_total": tmp_quests_total, "tmp_hp": tmp_hp, "tmp_turns": tmp_turns, "tmp_turns_to_time": tmp_turns_to_time, "tmp_expected_damage_to_hero_per_hit": tmp_expected_damage_to_hero_per_hit, "tmp_mob_hp": tmp_mob_hp, "tmp_power": tmp_power, "tmp_expected_damage_to_mob_per_hit": tmp_expected_damage_to_mob_per_hit, "tmp_expected_damage_to_hero_per_hit_interval": tmp_expected_damage_to_hero_per_hit_interval, "tmp_real_damage_to_mob_per_hit": tmp_real_damage_to_mob_per_hit, "tmp_real_damage_to_mob_per_hit_interval": tmp_real_damage_to_mob_per_hit_interval, "tmp_power_per_slot": tmp_power_per_slot, "tmp_battles_at_lvl": tmp_battles_at_lvl, "tmp_total_battles": tmp_total_battles, "tmp_artifacts_total": tmp_artifacts_total, "tmp_artifacts_per_battle": tmp_artifacts_per_battle, # 'tmp_gold_at_lvl': tmp_gold_at_lvl, "tmp_gold_in_day": tmp_gold_in_day, "tmp_total_gold_at_lvl": tmp_total_gold_at_lvl, }, )
def power(self): return Power.clean_power_for_hero_level(self.level) + self.equipment.get_power() @property
class ArtifactPrototype(object): __slots__ = ('record_id', 'power', 'level', 'bag_uuid', 'max_integrity', 'integrity', 'rarity') def __init__(self, record_id=None, power=None, bag_uuid=None, level=0, max_integrity=None, integrity=None, rarity=relations.RARITY.NORMAL): self.record_id = record_id self.power = power self.level = level self.rarity = rarity self.max_integrity = int(max_integrity if max_integrity is not None else rarity.max_integrity * random.uniform(1-c.ARTIFACT_MAX_INTEGRITY_DELTA, 1+c.ARTIFACT_MAX_INTEGRITY_DELTA)) self.integrity = integrity if integrity is not None else self.max_integrity self.bag_uuid = bag_uuid @property def record(self): from the_tale.game.artifacts import storage return storage.artifacts_storage[self.record_id] @property def id(self): return self.record.uuid @property def type(self): return self.record.type @property def name(self): return self.record.name @property def utg_name(self): return self.record.utg_name @property def utg_name_form(self): return self.record.utg_name_form @property def min_lvl(self): return self.record.min_lvl @property def max_lvl(self): return self.record.max_lvl @property def is_useless(self): return self.record.is_useless @property def can_be_equipped(self): return not self.type.is_USELESS def set_bag_uuid(self, uuid): self.bag_uuid = uuid def linguistics_restrictions(self): from the_tale.linguistics.relations import TEMPLATE_RESTRICTION_GROUP from the_tale.linguistics.storage import restrictions_storage return (restrictions_storage.get_restriction(TEMPLATE_RESTRICTION_GROUP.ARTIFACT_TYPE, self.type.value).id, restrictions_storage.get_restriction(TEMPLATE_RESTRICTION_GROUP.ARTIFACT_POWER_TYPE, self.record.power_type.value).id, restrictions_storage.get_restriction(TEMPLATE_RESTRICTION_GROUP.ARTIFACT_RARITY, self.rarity.value).id, restrictions_storage.get_restriction(TEMPLATE_RESTRICTION_GROUP.ARTIFACT_EFFECT, self._effect().TYPE.value).id, restrictions_storage.get_restriction(TEMPLATE_RESTRICTION_GROUP.ARTIFACT, self.record.id).id) def absolute_sell_price(self): if self.is_useless: gold_amount = 1 + int(f.normal_loot_cost_at_lvl(self.level)) else: gold_amount = 1 + int(f.sell_artifact_price(self.level) * self.rarity.cost) return gold_amount def get_sell_price(self): return int(self.absolute_sell_price()) def _effect(self): if self.rarity.is_NORMAL: return effects.NoEffect elif self.rarity.is_RARE: return effects.EFFECTS[self.record.rare_effect] elif self.rarity.is_EPIC: return effects.EFFECTS[self.record.epic_effect] else: raise exceptions.UnknownRarityType(type=self.rarity) def special_effect(self): return effects.EFFECTS[self.record.special_effect] def all_effects(self): return (self._effect(), self.special_effect()) def modify_attribute(self, type_, value): for effect in self.all_effects(): value = effect.modify_attribute(type_, value) return value def must_be_removed_on_help(self): return any(effect.REMOVE_ON_HELP for effect in self.all_effects()) def is_child_gift(self): return any(effect.TYPE.is_CHILD_GIFT for effect in self.all_effects()) def serialize(self): return {'id': self.id, 'power': self.power.serialize(), 'bag_uuid': self.bag_uuid, 'integrity': (self.integrity, self.max_integrity), 'rarity': self.rarity.value, 'level': self.level} @classmethod def deserialize(cls, data): # if artifact record is desabled or deleted, get another random record from the_tale.game.artifacts.storage import artifacts_storage record = artifacts_storage.get_by_uuid(data['id']) if record is None or record.state.is_DISABLED: record = random.choice(artifacts_storage.artifacts) integrity = data.get('integrity', [c.ARTIFACT_MAX_INTEGRITY, c.ARTIFACT_MAX_INTEGRITY]) return cls(record_id=record.id, power=Power.deserialize(data['power']), bag_uuid=data['bag_uuid'], integrity=integrity[0], max_integrity=integrity[1], rarity=relations.RARITY.index_value[data.get('rarity', relations.RARITY.NORMAL.value)], level=data.get('level', 1)) @classmethod def _preference_rating(cls, rarity, power, distribution): return (power.physic * distribution.physic + power.magic * distribution.magic) * rarity.preference_rating def preference_rating(self, distribution): return self._preference_rating(self.rarity, self.power, distribution) def make_better_than(self, artifact, distribution): while self.preference_rating(distribution) <= artifact.preference_rating(distribution): if random.uniform(0, 1) < distribution.physic: self.power.physic += 1 else: self.power.magic += 1 def sharp(self, distribution, max_power, force=False): choices = [] if force or self.power.physic < max_power.physic: choices.append(('physic', distribution.physic)) if force or self.power.magic < max_power.magic: choices.append(('magic', distribution.magic)) if not choices: return False if random_value_by_priority(choices) == 'physic': self.power.physic += 1 else: self.power.magic += 1 self.max_integrity -= int(self.max_integrity * c.ARTIFACT_SHARP_MAX_INTEGRITY_LOST_FRACTION) self.integrity = min(self.integrity, self.max_integrity) return True @property def integrity_fraction(self): if self.max_integrity == 0: return 0 return float(self.integrity) / self.max_integrity def damage_integrity(self): self.integrity = max(0, self.integrity - c.ARTIFACT_INTEGRITY_DAMAGE_PER_BATTLE) def can_be_broken(self): return self.integrity < self.max_integrity * (1.0 - c.ARTIFACT_INTEGRITY_SAFE_BARRIER) def break_it(self): self.power = Power(physic=max(1, int(self.power.physic * (1 - random.uniform(*c.ARTIFACT_BREAK_POWER_FRACTIONS)) - 1)), magic=max(1, int(self.power.magic * (1 - random.uniform(*c.ARTIFACT_BREAK_POWER_FRACTIONS)) - 1)) ) self.max_integrity = int(self.max_integrity * (1 - random.uniform(*c.ARTIFACT_BREAK_INTEGRITY_FRACTIONS))) self.integrity = min(self.integrity, self.max_integrity) def repair_it(self): self.integrity = self.max_integrity def ui_info(self, hero): effect = self._effect().TYPE special_effect = self.special_effect().TYPE return {'type': self.type.value, 'id': self.record.id, 'equipped': self.can_be_equipped, 'name': self.name, 'integrity': (self.integrity if not self.type.is_USELESS else None, self.max_integrity if not self.type.is_USELESS else None), 'rarity': self.rarity.value if not self.type.is_USELESS else None, 'effect': effect.value, 'special_effect': special_effect.value, 'preference_rating': self.preference_rating(hero.preferences.archetype.power_distribution) if not self.type.is_USELESS else None, 'power': self.power.ui_info() if not self.type.is_USELESS else None} def __eq__(self, other): return (self.record.id == other.record.id and self.power == other.power and self.level == other.level and self.integrity == other.integrity and self.max_integrity == other.max_integrity and self.bag_uuid == other.bag_uuid) NORMAL_ARTIFACT_LABEL = u'<span class="normal-artifact-label">%s</span> <span class="physic-label">%d</span> <span class="magic-label">%d</span>' RARE_ARTIFACT_LABEL = u'<span class="rare-artifact-label">%s</span> <span class="physic-label">%d</span> <span class="magic-label">%d</span>' EPIC_ARTIFACT_LABEL = u'<span class="epic-artifact-label">%s</span> <span class="physic-label">%d</span> <span class="magic-label">%d</span>' def html_label(self): if self.is_useless: return self.name if self.rarity.is_NORMAL: return self.NORMAL_ARTIFACT_LABEL % (self.name, self.power.physic, self.power.magic) if self.rarity.is_RARE: return self.RARE_ARTIFACT_LABEL % (self.name, self.power.physic, self.power.magic) if self.rarity.is_EPIC: return self.EPIC_ARTIFACT_LABEL % (self.name, self.power.physic, self.power.magic)
def show_balance(self): # pylint: disable=R0914 tmp_time = ['начало', '8 часов', 'день', 'неделя', 'месяц', '3 месяца', '6 месяцев', '1 год', '2 года', '3 года', '4 года', '5 лет', '6 лет'] tmp_times = [0, 8, 24, 24*7, 24*30, 24*30*3, 24*30*6, 24*30*12, 24*30*12*2, 24*30*12*3, 24*30*12*4, 24*30*12*5, 24*30*12*6] tmp_lvls = list(map(f.lvl_after_time, tmp_times)) # Всё, что ниже, должно зависеть от уровня, не от времени, т.к. время в данном случае не точный параметр, а анализ всё равно ориентируется на уровень. exp_for_quest = f.experience_for_quest__real(c.QUEST_AREA_RADIUS) tmp_exp_to_level = list(map(math.floor, list(map(f.exp_on_lvl, tmp_lvls)))) tmp_exp_total = list(map(math.floor, list(map(f.total_exp_to_lvl, tmp_lvls)))) tmp_quests_to_level = list(map(math.ceil, (exp/float(exp_for_quest) for exp in tmp_exp_to_level))) tmp_quests_total = list(map(math.ceil, (exp/float(exp_for_quest) for exp in tmp_exp_total))) dstr = PowerDistribution(0.5, 0.5) tmp_hp = list(map(f.hp_on_lvl, tmp_lvls)) tmp_turns = list(map(f.turns_on_lvl, tmp_lvls)) tmp_turns_to_time = list(map(int, list(map(f.hours_to_turns, tmp_times)))) tmp_expected_damage_to_hero_per_hit = list(map(f.expected_damage_to_hero_per_hit, tmp_lvls)) tmp_expected_damage_to_hero_per_hit_interval = [ (int(round(dmg*(1-c.DAMAGE_DELTA))), int(round(dmg*(1+c.DAMAGE_DELTA)))) for dmg in tmp_expected_damage_to_hero_per_hit] tmp_mob_hp = list(map(f.mob_hp_to_lvl, tmp_lvls)) tmp_power = [Power.power_to_level(dstr, lvl) for lvl in tmp_lvls] tmp_expected_damage_to_mob_per_hit = list(map(f.expected_damage_to_mob_per_hit, tmp_lvls)) tmp_real_damage_to_mob_per_hit = [p.damage().total for p in tmp_power] tmp_real_damage_to_mob_per_hit_interval = [ (int(round(dmg*(1-c.DAMAGE_DELTA))), int(round(dmg*(1+c.DAMAGE_DELTA)))) for dmg in tmp_real_damage_to_mob_per_hit] tmp_power_per_slot = [Power.power_to_artifact(dstr, lvl) for lvl in tmp_lvls] tmp_battles_at_lvl = list(map(math.floor, [x * c.BATTLES_PER_HOUR for x in map(f.time_on_lvl, tmp_lvls)])) tmp_total_battles = list(map(math.floor, [x * c.BATTLES_PER_HOUR for x in map(f.total_time_for_lvl, tmp_lvls)])) tmp_artifacts_per_battle = [c.ARTIFACTS_PER_BATTLE]* len(tmp_lvls) tmp_artifacts_total = [c.ARTIFACTS_LOOT_PER_DAY * f.total_time_for_lvl(lvl-1)/24.0 for lvl in tmp_lvls] tmp_gold_in_day = list(map(f.expected_gold_in_day, tmp_lvls)) tmp_total_gold_at_lvl = list(map(f.total_gold_at_lvl, tmp_lvls)) return self.template('balance/balance.html', {'c': c, 'f': f , 'exp_for_quest': exp_for_quest, 'average_path_length': c.QUEST_AREA_RADIUS, 'tmp_time': tmp_time, 'tmp_lvls': tmp_lvls, 'tmp_exp_to_level': tmp_exp_to_level, 'tmp_exp_total': tmp_exp_total, 'tmp_quests_to_level': tmp_quests_to_level, 'tmp_quests_total': tmp_quests_total, 'tmp_hp': tmp_hp, 'tmp_turns': tmp_turns, 'tmp_turns_to_time': tmp_turns_to_time, 'tmp_expected_damage_to_hero_per_hit': tmp_expected_damage_to_hero_per_hit, 'tmp_mob_hp': tmp_mob_hp, 'tmp_power': tmp_power, 'tmp_expected_damage_to_mob_per_hit': tmp_expected_damage_to_mob_per_hit, 'tmp_expected_damage_to_hero_per_hit_interval': tmp_expected_damage_to_hero_per_hit_interval, 'tmp_real_damage_to_mob_per_hit': tmp_real_damage_to_mob_per_hit, 'tmp_real_damage_to_mob_per_hit_interval': tmp_real_damage_to_mob_per_hit_interval, 'tmp_power_per_slot': tmp_power_per_slot, 'tmp_battles_at_lvl': tmp_battles_at_lvl, 'tmp_total_battles': tmp_total_battles, 'tmp_artifacts_total': tmp_artifacts_total, 'tmp_artifacts_per_battle': tmp_artifacts_per_battle, # 'tmp_gold_at_lvl': tmp_gold_at_lvl, 'tmp_gold_in_day': tmp_gold_in_day, 'tmp_total_gold_at_lvl': tmp_total_gold_at_lvl } )
def increment_equipment_rarity(self, artifact): artifact.rarity = artifacts_relations.RARITY(artifact.rarity.value+1) artifact.power = Power.artifact_power_randomized(distribution=artifact.record.power_type.distribution, level=self.level) artifact.max_integrity = int(artifact.rarity.max_integrity * random.uniform(1-c.ARTIFACT_MAX_INTEGRITY_DELTA, 1+c.ARTIFACT_MAX_INTEGRITY_DELTA)) self.reset_accessors_cache()