def pick_a_spell(self, magic_only=False, custom=None): if magic_only: spells = filter(lambda s: s.spellid in range(0, 36), all_spells) else: spells = all_spells if custom: spells = filter(custom, spells) spells = sorted(spells, key=lambda s: s.rank()) items = get_ranked_items() index = items.index(self) index = int((index / float(len(items))) * len(spells)) index = mutate_index(index, len(spells), [False, True, True], (-5, 4), (-3, 3)) spell = spells[index] return spell, index / float(len(spells))
def mutate_contents(self, guideline=None, monster=None, guarantee_miab_treasure=False, enemy_limit=None, uniqueness=False, crazy_prices=False, uncapped_monsters=False): global used_formations, done_items if self.do_not_mutate and self.contents is not None: return if self.value is not None: value = self.value else: value = self.get_current_value(guideline=guideline) items = get_ranked_items() itemids = [i.itemid for i in items] if self.treasure: try: index = itemids.index(self.contents) except ValueError: index = 0 indexed_item = items[index] else: lowpriced = [i for i in items if i.rank() <= value * 100] if not lowpriced: lowpriced = items[:random.randint(1, 16)] index = max(0, len(lowpriced) - 1) indexed_item = lowpriced[index] chance = random.randint(1, 50) orphaned_formations = get_orphaned_formations(uncapped_monsters) orphaned_formations = [ f for f in orphaned_formations if f not in used_formations ] extra_miabs = get_extra_miabs(0) if monster is True: chance = 1 elif monster is False: chance += 3 chance = min(chance, 50) else: if orphaned_formations or extra_miabs: chance -= 2 if uncapped_monsters else 1 chance = max(chance, 1) formations = get_appropriate_formations() formations = [ f for f in formations if f.get_guaranteed_drop_value() >= value * 100 ] if 1 <= chance <= 3 and (self.rank or formations): # monster self.set_content_type(0x20) from locationrandomizer import get_location rank = self.rank if self.is_clock or not rank: rank = min(formations, key=lambda f: f.rank()).rank() if formations else 0 chosen = select_monster_in_a_box( rank=rank, value=value, clock=self.is_clock or monster is True, old_version=uncapped_monsters, guarantee_miab_treasure=guarantee_miab_treasure, enemy_limit=enemy_limit) chosen = get_2pack(chosen) # only 2-packs are allowed self.contents = chosen.setid & 0xFF elif 4 <= chance <= 5: # gold self.set_content_type(0x80) if crazy_prices: value = random.randint(10, 50) else: value = value // 2 value += (random.randint(0, value) + random.randint(0, value)) self.contents = min(0xFF, max(1, value)) if self.contents == 0xFF: self.contents -= random.randint(0, 20) + random.randint(0, 20) else: # treasure self.set_content_type(0x40) if uniqueness and random.randint(1, 7) != 7: if len(done_items) >= len(items): done_items = [] temp = [ i for i in items if i == indexed_item or i not in done_items ] if len(temp) > 1: items = temp index = items.index(indexed_item) if indexed_item in done_items: items.remove(indexed_item) index = mutate_index(index, len(items), [False, True], (-4, 2), (-2, 2)) self.contents = items[index].itemid done_items.append(items[index]) assert self.contents <= 0xFF self.value = value
def select_monster_in_a_box(rank, value, clock, guarantee_miab_treasure, enemy_limit, old_version): formations = get_appropriate_formations() formations = [ f for f in formations if f.get_guaranteed_drop_value() >= value * 100 ] orphaned_formations = get_orphaned_formations(old_version) orphaned_formations = [ f for f in orphaned_formations if f not in used_formations ] extra_miabs = get_extra_miabs(0) normal_rank_limit = lambda rank: 9 / 5 * rank - 150 special_rank_limit = lambda rank: 5 / 4000 * rank * rank + 7 / 4 * rank - 300 if guarantee_miab_treasure: extra_miabs = [] orphaned_formations = [] candidates = [] else: if len(extra_miabs) > 1: extra_miabs = get_extra_miabs(rank) if orphaned_formations or extra_miabs: max_rank = math.inf if ( clock or old_version) else normal_rank_limit(rank) formations = [ f for f in formations if f.rank() >= rank and f.rank() < max_rank ] if old_version: formations = formations[:random.randint(1, 3)] else: formations = [ f for f in formations if f not in used_formations ] formations = [ f for f in formations if f.formid not in banned_formids ] formations = formations[:random.randint(2, 6)] if not (clock or old_version): orphaned_formations = [ f for f in orphaned_formations if f.rank() < normal_rank_limit(rank) and f.get_guaranteed_drop_value() >= value * 20 - 1000 ] max_extra_miab_rank = special_rank_limit(rank) extra_miabs = [ f for f in extra_miabs if f.rank() <= max_extra_miab_rank ] candidates = (orphaned_formations + extra_miabs) candidates = [c for c in candidates if c not in used_formations] candidates = [c for c in candidates if c.formid not in banned_formids] candidates = sorted(set(candidates), key=lambda f: f.rank()) if len(candidates) != 1: candidates += formations candidates = [c for c in candidates if c not in used_formations] candidates = [c for c in candidates if c.formid not in banned_formids] if enemy_limit is not None: candidates = [f for f in candidates if f.rank() <= enemy_limit] rank_multiplier = 1.5 value_divisor = 8 while not candidates: max_rank = max(rank, rank_multiplier * normal_rank_limit(rank)) min_value = value * 100 / value_divisor - 1500 orphaned_formations = get_orphaned_formations(old_version) orphaned_formations = [ f for f in orphaned_formations if f.rank() <= max_rank and f.get_guaranteed_drop_value() >= min_value / 3 - 1200 ] extra_miabs = get_extra_miabs(0) max_extra_miab_rank = special_rank_limit(rank) extra_miabs = [ f for f in extra_miabs if f.rank() <= max_extra_miab_rank * rank_multiplier ] candidates = (orphaned_formations + extra_miabs) candidates = [c for c in candidates if c not in used_formations] candidates = [c for c in candidates if c.formid not in banned_formids] if len(candidates) != 1: formations = [ c for c in appropriate_formations if c.rank() <= max_rank and c.get_guaranteed_drop_value() >= min_value ] formations = [c for c in formations if c not in used_formations] formations = [ c for c in formations if c.formid not in banned_formids ] formations = formations[:4] candidates += formations rank_multiplier *= 1.25 value_divisor *= 2 if rank_multiplier < 5 and enemy_limit is not None: candidates = [f for f in candidates if f.rank() <= enemy_limit] candidates = sorted(candidates, key=lambda f: f.rank()) half = len(candidates) // 2 candidates = candidates[half:] index = random.randint(0, half) + random.randint(0, half) index = min(index, len(candidates) - 1) candidates = candidates[index:] candidates = sorted(candidates, key=lambda f: f.rank()) if orphaned_formations: index = max(0, len([c for c in candidates if c.rank() <= rank]) - 1) index = mutate_index(index, len(candidates), [False, True], (-3, 2), (-1, 1)) else: index = 0 index = mutate_index(index, len(candidates), [False, True], (-1, 4), (-1, 1)) chosen = candidates[index] for m in chosen.present_enemies: m.auxloc = "Monster-in-a-Box" banned_formids.append(chosen.formid) used_formations.append(chosen) return chosen
def mutate_contents(self, guideline=None, monster=None, guarantee_miab_treasure=False, enemy_limit=None, uniqueness=False): global used_formations, done_items if self.do_not_mutate and self.contents is not None: return if self.value is not None: value = self.value else: value = self.get_current_value(guideline=guideline) items = get_ranked_items() itemids = [i.itemid for i in items] if self.treasure: try: index = itemids.index(self.contents) except ValueError: index = 0 indexed_item = items[index] else: lowpriced = [i for i in items if i.rank() <= value*100] if not lowpriced: lowpriced = items[:random.randint(1, 16)] index = max(0, len(lowpriced)-1) indexed_item = lowpriced[index] chance = random.randint(1, 50) orphaned_formations = get_orphaned_formations() orphaned_formations = [f for f in orphaned_formations if f not in used_formations] extra_miabs = get_extra_miabs(0) if orphaned_formations or extra_miabs: chance -= 2 chance = max(chance, 1) if monster is True: chance = 1 elif monster is False: chance += 3 chance = min(chance, 50) formations = get_appropriate_formations() formations = [f for f in formations if f.get_guaranteed_drop_value() >= value * 100] if 1 <= chance <= 3 and (self.rank or formations): # monster self.set_content_type(0x20) rank = self.rank or min(formations, key=lambda f: f.rank()).rank() if guarantee_miab_treasure: extra_miabs = [] orphaned_formations = [] candidates = [] else: if len(extra_miabs) > 1: extra_miabs = get_extra_miabs(rank) if orphaned_formations or extra_miabs: formations = [f for f in formations if f.rank() >= rank] formations = formations[:random.randint(1, 3)] candidates = (orphaned_formations + extra_miabs) candidates = sorted(set(candidates)) if len(candidates) != 1: candidates += formations candidates = [c for c in candidates if c not in used_formations] candidates = [c for c in candidates if c.formid not in banned_formids] if enemy_limit is not None: candidates = [f for f in candidates if f.rank() <= enemy_limit] if not candidates: candidates = (formations + get_orphaned_formations() + get_extra_miabs(0)) if enemy_limit is not None: candidates = [f for f in candidates if f.rank() <= enemy_limit] candidates = sorted(candidates, key=lambda f: f.rank()) half = len(candidates) / 2 candidates = candidates[half:] index = random.randint(0, half) + random.randint(0, half) index = min(index, len(candidates)-1) candidates = candidates[index:] candidates = sorted(candidates, key=lambda f: f.rank()) if orphaned_formations: index = max( 0, len([c for c in candidates if c.rank() <= rank])-1) index = mutate_index(index, len(candidates), [False, True], (-3, 2), (-1, 1)) else: index = 0 index = mutate_index(index, len(candidates), [False, True], (-1, 4), (-1, 1)) chosen = candidates[index] for m in chosen.present_enemies: m.auxloc = "Monster-in-a-Box" banned_formids.append(chosen.formid) used_formations.append(chosen) chosen = get_2pack(chosen) # only 2-packs are allowed self.contents = chosen.setid & 0xFF elif 4 <= chance <= 5: # gold self.set_content_type(0x80) value = value / 2 value += (random.randint(0, value) + random.randint(0, value)) self.contents = min(0xFF, max(1, value)) if self.contents == 0xFF: self.contents -= random.randint(0, 20) + random.randint(0, 20) else: # treasure self.set_content_type(0x40) if uniqueness and random.randint(1, 7) != 7: if len(done_items) >= len(items): done_items = [] temp = [i for i in items if i == indexed_item or i not in done_items] if len(temp) > 1: items = temp index = items.index(indexed_item) if indexed_item in done_items: items.remove(indexed_item) index = mutate_index(index, len(items), [False, True], (-4, 2), (-2, 2)) self.contents = items[index].itemid done_items.append(items[index]) assert self.contents <= 0xFF self.value = value
def mutate_contents(self, guideline=None, monster=None, guarantee_miab_treasure=False, enemy_limit=None, uniqueness=False): global used_formations, done_items if self.do_not_mutate and self.contents is not None: return if self.value is not None: value = self.value else: value = self.get_current_value(guideline=guideline) items = get_ranked_items() itemids = [i.itemid for i in items] if self.treasure: try: index = itemids.index(self.contents) except ValueError: index = 0 indexed_item = items[index] else: lowpriced = [i for i in items if i.rank() <= value * 100] if not lowpriced: lowpriced = items[:random.randint(1, 16)] index = max(0, len(lowpriced) - 1) indexed_item = lowpriced[index] chance = random.randint(1, 50) orphaned_formations = get_orphaned_formations() orphaned_formations = [ f for f in orphaned_formations if f not in used_formations ] extra_miabs = get_extra_miabs(0) if orphaned_formations or extra_miabs: chance -= 2 chance = max(chance, 1) if monster is True: chance = 1 elif monster is False: chance += 3 chance = min(chance, 50) formations = get_appropriate_formations() formations = [ f for f in formations if f.get_guaranteed_drop_value() >= value * 100 ] if 1 <= chance <= 3 and (self.rank or formations): # monster self.set_content_type(0x20) rank = self.rank or min(formations, key=lambda f: f.rank()).rank() if guarantee_miab_treasure: extra_miabs = [] orphaned_formations = [] candidates = [] else: if len(extra_miabs) > 1: extra_miabs = get_extra_miabs(rank) if orphaned_formations or extra_miabs: formations = [f for f in formations if f.rank() >= rank] formations = formations[:random.randint(1, 3)] candidates = (orphaned_formations + extra_miabs) candidates = sorted(set(candidates)) if len(candidates) != 1: candidates += formations candidates = [c for c in candidates if c not in used_formations] candidates = [ c for c in candidates if c.formid not in banned_formids ] if enemy_limit is not None: candidates = [f for f in candidates if f.rank() <= enemy_limit] if not candidates: candidates = (formations + get_orphaned_formations() + get_extra_miabs(0)) if enemy_limit is not None: candidates = [ f for f in candidates if f.rank() <= enemy_limit ] candidates = sorted(candidates, key=lambda f: f.rank()) half = len(candidates) / 2 candidates = candidates[half:] index = random.randint(0, half) + random.randint(0, half) index = min(index, len(candidates) - 1) candidates = candidates[index:] candidates = sorted(candidates, key=lambda f: f.rank()) if orphaned_formations: index = max( 0, len([c for c in candidates if c.rank() <= rank]) - 1) index = mutate_index(index, len(candidates), [False, True], (-3, 2), (-1, 1)) else: index = 0 index = mutate_index(index, len(candidates), [False, True], (-1, 4), (-1, 1)) chosen = candidates[index] for m in chosen.present_enemies: m.auxloc = "Monster-in-a-Box" banned_formids.append(chosen.formid) used_formations.append(chosen) chosen = get_2pack(chosen) # only 2-packs are allowed self.contents = chosen.setid & 0xFF elif 4 <= chance <= 5: # gold self.set_content_type(0x80) value = value / 2 value += (random.randint(0, value) + random.randint(0, value)) self.contents = min(0xFF, max(1, value)) if self.contents == 0xFF: self.contents -= random.randint(0, 20) + random.randint(0, 20) else: # treasure self.set_content_type(0x40) if uniqueness and random.randint(1, 7) != 7: if len(done_items) >= len(items): done_items = [] temp = [ i for i in items if i == indexed_item or i not in done_items ] if len(temp) > 1: items = temp index = items.index(indexed_item) if indexed_item in done_items: items.remove(indexed_item) index = mutate_index(index, len(items), [False, True], (-4, 2), (-2, 2)) self.contents = items[index].itemid done_items.append(items[index]) assert self.contents <= 0xFF self.value = value