Ejemplo n.º 1
0
    def get_current_value(self, guideline=None):
        if self.treasure:
            items = get_ranked_items()
            itemids = [i.itemid for i in items]
            try:
                index = itemids.index(self.contents)
                value = items[index].rank() / 100
            except ValueError:
                value = 100
        elif self.gold or self.empty:
            if self.empty:
                if guideline is not None:
                    value = guideline / 100
                else:
                    raise Exception("No guideline provided for empty chest.")
            else:
                value = self.contents
        elif self.monster:
            from formationrandomizer import get_fset
            formation = get_fset(self.contents | 0x100).formations[0]
            items = []
            for monster in formation.present_enemies:
                mitems = [i for i in monster.drops if i is not None]
                if mitems:
                    items.append(min(mitems, key=lambda i: i.rank()))
            if items:
                highest = max(items, key=lambda i: i.rank())
                value = highest.rank() / 100
            else:
                value = 1

        assert value < 10000
        return value
Ejemplo n.º 2
0
    def get_current_value(self, guideline=None):
        if self.treasure:
            items = get_ranked_items()
            itemids = [i.itemid for i in items]
            try:
                index = itemids.index(self.contents)
                value = items[index].rank() // 100
            except ValueError:
                value = 100
        elif self.gold or self.empty:
            if self.empty:
                if guideline is not None:
                    value = guideline // 100
                else:
                    raise Exception("No guideline provided for empty chest.")
            else:
                value = self.contents
        elif self.monster:
            from formationrandomizer import get_fset
            formation = get_fset(self.contents | 0x100).formations[0]
            items = []
            for monster in formation.present_enemies:
                mitems = [i for i in monster.original_drops if i is not None]
                if mitems:
                    items.append(min(mitems, key=lambda i: i.rank()))
            if items:
                highest = max(items, key=lambda i: i.rank())
                value = highest.rank() // 100
            else:
                value = 1

        assert value < 10000
        return value
Ejemplo n.º 3
0
 def get_notable_equips(self):
     items = [i for i in get_ranked_items() if
              i.equippable & (1 << self.id) and not i.imp_only]
     weapons = [i for i in items if i.is_weapon]
     rare = [i for i in items if not i.is_weapon and
             bin(i.equippable).count('1') <= 5 and
             i.rank() > 4000]
     rare.extend([w for w in weapons if w.rank() > 50000])
     if self.id == 12:
         rare = [r for r in rare if not r.features['special1'] & 0x7C]
     notable = []
     if weapons:
         weapons = sorted(weapons, key=lambda w: w.rank(), reverse=True)
         notable.extend(weapons[:2])
     if rare:
         rare = sorted(rare, key=lambda r: r.rank(), reverse=True)
         notable.extend(rare[:8])
     notable = set(notable)
     return sorted(notable, key=lambda n: n.itemid)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    def mutate_items(self, fout, crazy_shops=False):
        items = get_ranked_items()
        if crazy_shops:
            weapons_tools = [i for i in items if i.is_weapon or i.is_tool]
            armors = [i for i in items if i.is_armor]
            relics = [i for i in items if i.is_relic]
            consumables = [i for i in items if i.is_consumable]

            types = [weapons_tools, armors, relics, consumables]

            valid_items = items
        elif self.shoptype == 1:
            valid_items = [c for c in items if c.is_weapon or c.is_tool]
        elif self.shoptype == 2:
            valid_items = [c for c in items if c.is_armor]
        elif self.shoptype == 3:
            valid_items = [
                c for c in items
                if not (c.is_weapon or c.is_armor or c.is_relic)
            ]
        elif self.shoptype == 4:
            valid_items = [c for c in items if c.is_relic]
        elif self.shoptype == 5:
            valid_items = list(items)

        old_items = [i for i in self.items if i != 0xFF]
        if not old_items:
            return
        old_items = [get_item(i) for i in old_items]
        old_items = [i for i in old_items if i]

        if len(old_items) == 0:
            average_value = 0
        else:
            average_value = sum([i.rank() for i in old_items]) / len(old_items)
        average_item = len(
            [i for i in valid_items if i.rank() <= average_value])
        average_item += -1
        average_item = valid_items[average_item]

        while (crazy_shops
               or random.randint(1, 3) == 3) and len(old_items) < 8:
            old_items.append(average_item)
        new_items = []

        for item in old_items:
            if crazy_shops:
                item_type = random.choice(types)
                new_items.append(random.choice(item_type))
            else:
                if random.randint(1, 10) == 10:
                    candidates = items
                else:
                    candidates = valid_items

                try:
                    index = candidates.index(item)
                except ValueError:
                    continue

                while random.randint(1, 3) < 3:
                    index += random.randint(-2, 2)
                    index = max(0, min(index, len(candidates) - 1))
                new_items.append(candidates[index])

        if not new_items:
            return

        for i in new_items:
            if i.price < 3:
                price = i.rank()
                modifier = price // 2
                price += random.randint(0, modifier)
                while random.randint(1, 4) < 4:
                    price += random.randint(0, modifier)
                price = min(price, 0xFEFE)
                i.price = price

                zerocount = 0
                while i.price > 100:
                    i.price = i.price // 10
                    zerocount += 1

                while zerocount > 0:
                    i.price = i.price * 10
                    zerocount += -1

                i.write_stats(fout)

        self.items = [i.itemid for i in new_items]
        self.items = sorted(set(self.items))
        while len(self.items) < 8:
            self.items.append(0xFF)

        assert len(self.items) == 8
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    def mutate_items(self, fout):
        items = get_ranked_items()
        if self.shoptype == 1:
            valid_items = [c for c in items if c.is_weapon or c.is_tool]
        elif self.shoptype == 2:
            valid_items = [c for c in items if c.is_armor]
        elif self.shoptype == 3:
            valid_items = [c for c in items if not (c.is_weapon or c.is_armor or c.is_relic)]
        elif self.shoptype == 4:
            valid_items = [c for c in items if c.is_relic]
        elif self.shoptype == 5:
            valid_items = list(items)

        old_items = [i for i in self.items if i != 0xFF]
        if not old_items:
            return
        old_items = [get_item(i) for i in old_items]
        old_items = [i for i in old_items if i]

        if len(old_items) == 0:
            average_value = 0
        else:
            average_value = sum([i.rank() for i in old_items]) / len(old_items)
        average_item = len([i for i in valid_items if i.rank() <= average_value])
        average_item += -1
        average_item = valid_items[average_item]

        while random.randint(1, 3) == 3 and len(old_items) < 8:
            old_items.append(average_item)
        new_items = []
        for item in old_items:
            if random.randint(1, 10) == 10:
                candidates = items
            else:
                candidates = valid_items

            try:
                index = candidates.index(item)
            except ValueError:
                continue

            while random.randint(1, 3) < 3:
                index += random.randint(-2, 2)
                index = max(0, min(index, len(candidates)-1))
            new_items.append(candidates[index])

        if not new_items:
            return

        for i in new_items:
            if i.price < 3:
                price = i.rank()
                modifier = price / 2
                price += random.randint(0, modifier)
                while random.randint(1, 4) < 4:
                    price += random.randint(0, modifier)
                price = min(price, 0xFEFE)
                i.price = price

                zerocount = 0
                while i.price > 100:
                    i.price = i.price / 10
                    zerocount += 1

                while zerocount > 0:
                    i.price = i.price * 10
                    zerocount += -1

                i.write_stats(fout)

        self.items = [i.itemid for i in new_items]
        self.items = sorted(set(self.items))
        while len(self.items) < 8:
            self.items.append(0xFF)

        assert len(self.items) == 8