Exemplo n.º 1
0
    def mutate(self):
        MAX_ENEMIES = 6
        if self.bosses or self.enemies_hidden or not self.enemies_present:
            return
        candidates = list(self.leaders)
        while len(candidates) < 3:
            base = random.choice(candidates)
            new = base.get_similar()
            if new not in candidates:
                candidates.append(new)
        assert len(set(candidates)) <= 3
        num_enemies = random.randint(1, random.randint(3, MAX_ENEMIES))
        num_enemies = max(num_enemies, len(self.leaders))
        chosen_enemies = list(self.leaders)
        while len(chosen_enemies) < num_enemies:
            vram_total = sum([e.vram_value for e in chosen_enemies])
            sub_candidates = candidates + chosen_enemies
            sub_candidates = [e for e in sub_candidates
                              if vram_total + e.vram_value <= 64]
            if not sub_candidates:
                num_enemies = len(chosen_enemies)
                break
            chosen_enemies.append(random.choice(sub_candidates))
        random.shuffle(chosen_enemies)

        def mutate_coordinate((x, y)):
            x = mutate_normal(x, minimum=self.lower_x, maximum=self.upper_x)
            y = mutate_normal(y, minimum=self.lower_y, maximum=self.upper_y)
            return (x, y)

        def get_distance((x1, y1), (x2, y2)):
            return ((x1-x2)**2 + (y1-y2)**2)**0.5
Exemplo n.º 2
0
    def mutate(self):
        global chest_items
        if self.is_key:
            return

        if self.index in [0x6A, 0x6B, 0x6C, 0x6E]:
            self.contents = 0x2A
            return

        any_left = self.desirable_left + self.undesirable_left
        value = None
        if self.is_consumable and (not any_left or random.randint(1, 7) != 7):
            self.contents = random.choice(self.consumable_options)
            return
        elif self.is_consumable:
            if self.undesirable_left and (not self.desirable_left
                                          or random.randint(1, 10) != 10):
                value = self.undesirable_left.pop()
            else:
                value = self.desirable_left.pop()

        if value is None:
            if self.desirable_left:
                value = self.desirable_left.pop()
            elif self.undesirable_left:
                value = self.undesirable_left.pop()
            else:
                value = 0x12  # seed

        if (value not in [0x12, 0x14] and value in DESIRABLE_ITEMS
                and self.is_consumable):
            self.well_hidden.add(value)
        self.contents = value
Exemplo n.º 3
0
    def mutate_magic_bits(self):
        self.reseed(salt="magicbit")
        for attr in self.magic_bits_attributes:
            value = getattr(self, attr)
            sort_func = lambda x: (bin(value ^ x).count('1'), random.random(),
                                   value)
            all_values = set([o.old_data[attr] for o in self.every] + [value])
            all_values = sorted(all_values, key=sort_func)
            assert all_values[0] == value
            max_index = len(all_values) - 1
            a = random.randint(0,
                               random.randint(0, random.randint(0, max_index)))
            b = random.randint(0, max_index)
            if a > b:
                a, b = b, a
            index = int(
                round((b * self.random_degree) + (a *
                                                  (1 - self.random_degree))))
            new_value = all_values[index]
            assert (value | new_value) == 0xFFFF & (value | new_value)
            new_value = new_value ^ value
            for i in xrange(16):
                mask = (1 << i)
                if random.random() > max(self.random_degree, 0.5):
                    if (new_value & mask):
                        new_value = new_value ^ mask

            value = value ^ new_value
            setattr(self, attr, value)
Exemplo n.º 4
0
    def mutate(self):
        global chest_items
        if self.is_key:
            return

        if self.index in [0x6A, 0x6B, 0x6C, 0x6E]:
            self.contents = 0x2A
            return

        any_left = self.desirable_left + self.undesirable_left
        value = None
        if self.is_consumable and (not any_left or random.randint(1, 7) != 7):
            self.contents = random.choice(self.consumable_options)
            return
        elif self.is_consumable:
            if self.undesirable_left and (
                    not self.desirable_left or random.randint(1, 10) != 10):
                value = self.undesirable_left.pop()
            else:
                value = self.desirable_left.pop()

        if value is None:
            if self.desirable_left:
                value = self.desirable_left.pop()
            elif self.undesirable_left:
                value = self.undesirable_left.pop()
            else:
                value = 0x12  # seed

        if (value not in [0x12, 0x14] and value in DESIRABLE_ITEMS
                and self.is_consumable):
            self.well_hidden.add(value)
        self.contents = value
Exemplo n.º 5
0
 def rank(self):
     if hasattr(self, "_rank"):
         return self._rank
     price = PriceObject.get(self.index).price
     if self.banned:
         self._rank = -1
     elif price == 0 and not self.is_key:
         self._rank = random.randint(1, random.randint(1, 999))
     elif price == 0:
         self._rank = -1
     elif self.is_frog_coin_item:
         self._rank = price * 50
     elif price > 1000:
         self._rank = price / 2
     elif self.rare and self.is_consumable:
         rank = 2 * price
         if price <= 50:
             rank = rank * 50
         if self.reuseable:
             rank = rank * 4
         self._rank = rank
     elif self.rare and self.is_armor:
         self._rank = price * 3
     elif self.index == 0x5e:  # quartz charm
         self._rank = 999
     elif self.rare and self.is_accessory:
         self._rank = price * 2
     else:
         self._rank = price
     self._rank += (1 - (self.index / 1000.0))
     return self.rank
Exemplo n.º 6
0
 def mutate_all(cls):
     for group in cls.groups.values():
         for o in group:
             while o.level >= 100 or o.level == 0:
                 other = random.choice(group)
                 o.level = random.randint(2, random.randint(2, 99))
                 o.increase = max(1, other.increase)
             o.mutate()
Exemplo n.º 7
0
 def mutate_all(cls):
     for group in cls.groups.values():
         for o in group:
             while o.level >= 100 or o.level == 0:
                 other = random.choice(group)
                 o.level = random.randint(2, random.randint(2, 99))
                 o.increase = max(1, other.increase)
             o.mutate()
Exemplo n.º 8
0
 def unbecome_frog_coin_item(self):
     if not self.is_frog_coin_item:
         return False
     factor = float(random.randint(50, random.randint(50, 100)))
     price = int(round(self.price * factor))
     PriceObject.get(self.index).price = min(price, 1998)
     self._is_frog_coin_item = False
     return True
Exemplo n.º 9
0
 def mutate(self):
     if random.choice([True, False]):
         level = max([r for r in self.reqs if 1 <= r <= 8])
     else:
         level = random.randint(1, 4) + random.randint(0, 4)
     newreqs = [level, random.randint(1, level)]
     if self.is_triple:
         newreqs.append(random.randint(1, level))
     random.shuffle(newreqs)
     self.reqs[:len(newreqs)] = newreqs
Exemplo n.º 10
0
 def mutate(self):
     if random.choice([True, False]):
         level = max([r for r in self.reqs if 1 <= r <= 8])
     else:
         level = random.randint(1, 4) + random.randint(0, 4)
     newreqs = [level, random.randint(1, level)]
     if self.is_triple:
         newreqs.append(random.randint(1, level))
     random.shuffle(newreqs)
     self.reqs[:len(newreqs)] = newreqs
Exemplo n.º 11
0
 def become_frog_coin_item(self):
     if self.is_frog_coin_item:
         return False
     factor = float(random.randint(random.randint(10, 50), 50))
     if self.rare:
         price = int(round(self.rank / factor))
     else:
         price = int(round(self.price / factor))
     PriceObject.get(self.index).price = min(max(price, 1), 50)
     self._is_frog_coin_item = True
     return True
Exemplo n.º 12
0
    def become_boss(self):
        flamerus_rank = MonsterObject.get(0x4a).rank
        battlefields = [
            bf for bf in BattleFormationObject.ranked if bf.index < 20
        ]
        my_index = battlefields.index(self)
        candidates = [
            m for m in MonsterObject.ranked if m.rank >= flamerus_rank
        ]
        new_index = int(round(my_index * (len(candidates) / 20.0)))
        new_index = mutate_normal(new_index,
                                  minimum=0,
                                  maximum=len(candidates) - 1)
        leader = candidates[new_index]
        candidates = [m for m in MonsterObject.ranked if m.rank < leader.rank]
        max_index = len(candidates) - 1
        follow_index = random.randint(random.randint(0, max_index), max_index)
        follower = candidates[follow_index].index
        if random.randint(0, max_index) >= follow_index:
            follow2_index = random.randint(
                random.randint(max_index - follow_index, max_index), max_index)
            follower2 = candidates[follow2_index].index
            new_ids = [follower, leader.index, follower2]
        else:
            new_ids = [leader.index, follower, 0xFF]
        f = FormationObject.get_unused()
        f.special_boss = True
        f.enemy_ids = new_ids
        self.formation_ids = [f.index] * 3
        f.mutated = True
        br = BattleRoundsObject.get(self.index)
        br.num_rounds = 1
        br.mutated = True

        if "t" not in get_flags():
            return
        br2 = BattleRewardObject.get(self.index)
        br2.reward = 0x4000
        done_items = [
            t.reward & 0xFF for t in BattleRewardObject.every
            if hasattr(t, "mutated") and t.mutated and t.reward & 0x4000
        ]
        if TreasureIndexObject.well_hidden:
            value = random.choice(sorted(TreasureIndexObject.well_hidden))
            TreasureIndexObject.well_hidden.remove(value)
        else:
            value = random.choice([
                i for i in DESIRABLE_ITEMS if i != 0x14 and i not in done_items
            ])
        br2.reward |= value
        br2.mutated = True
Exemplo n.º 13
0
    def mutate(self):
        super(ArmorObject, self).mutate()
        if random.randint(1, 4) == 4:
            self.element = shuffle_bits(self.element)
        else:
            value = shuffle_bits(self.element >> 3, size=5)
            value = value << 3
            self.element = self.element & 0x7
            self.element |= value

        if self.index + self.first_name_index not in UNDESIRABLE_ITEMS:
            if self.status & 0x80 and random.randint(1, 10) == 10:
                return
            self.status &= 0x7F
Exemplo n.º 14
0
    def mutate(self):
        super(ArmorObject, self).mutate()
        if random.randint(1, 4) == 4:
            self.element = shuffle_bits(self.element)
        else:
            value = shuffle_bits(self.element >> 3, size=5)
            value = value << 3
            self.element = self.element & 0x7
            self.element |= value

        if self.index + self.first_name_index not in UNDESIRABLE_ITEMS:
            if self.status & 0x80 and random.randint(1, 10) == 10:
                return
            self.status &= 0x7F
Exemplo n.º 15
0
 def nudge_hue(hue):  #designed for 'pure' hue: one 31, one 0, one anything
     new_color = hue[:]
     if len([h for h in hue if h not in [0, 31]]) > 0:
         new_color = [(h if h in [0, 31] else h + random.randint(-2, 2))
                      for h in hue]
     elif len([h for h in hue if h == 31]) >= 2:
         nudge_idx = random.choice(
             [i for i, h in enumerate(hue) if h == 31])
         new_color[nudge_idx] -= random.randint(0, 3)
     elif 0 in hue:
         nudge_idx = random.choice([i for i, h in enumerate(hue) if h == 0])
         new_color[nudge_idx] += random.randint(0, 3)
     new_color = [(c if c <= 31 else 31) for c in new_color]
     new_color = [(c if c >= 0 else 0) for c in new_color]  # just in case
     return new_color
Exemplo n.º 16
0
 def mutate(self):
     item = None
     if self.contents & 0x8000:
         value = (self.contents & 0x7FFF) << 1
     elif self.contents & 0xFF00:
         return
     else:
         item = ItemObject.get(self.contents & 0xff)
         if item is None:
             return
         if item.rare:
             new_item = item.get_similar()
             self.contents = new_item.full_index
             return
         elif not item.buyable:
             return
         value = item.rank_price
     if random.randint(1, 20) == 20:
         value = min(65000, max(0, value))
         value = mutate_normal(value,
                               minimum=0,
                               maximum=65000,
                               random_degree=self.random_degree)
         self.contents = 0x8000 | (value >> 1)
         return
     if item is None:
         item = [
             i for i in ItemObject.every_buyable if i.rank_price <= value
         ][-1]
     new_item = item.get_similar()
     self.contents = new_item.full_index
Exemplo n.º 17
0
    def randomize_all(cls):
        meats = {m.meat.old_data['meat'] for m in MonsterObject.every}
        for meat in sorted(meats):
            monsters = [m for m in MonsterObject.every
                        if m.meat.old_data['meat'] == meat
                        and m.index <= MonsterObject.MAX_EVOLVE_INDEX]
            if not monsters:
                assert meat >= 0xc0
                continue
            assert len(monsters) == 5
            assert monsters[-1].level == 0xb
            assert monsters == sorted(monsters, key=lambda m: m.level)
            new_levels = set([])
            for m in monsters[:4]:
                new_level = mutate_normal(
                    m.level, minimum=1, maximum=0xa, wide=True,
                    random_degree=MonsterLevelObject.random_degree)
                new_levels.add(new_level)

            while len(new_levels) < 4:
                new_levels.add(random.randint(1, 0xa))
            new_levels = sorted(new_levels)

            for level, monster in zip(new_levels, monsters):
                assert 1 <= level <= 0xa
                MonsterLevelObject.get(monster.index).set_level(level)

        super(MonsterLevelObject, cls).randomize_all()
Exemplo n.º 18
0
 def mutate(self):
     item = None
     if self.contents & 0x8000:
         value = (self.contents & 0x7FFF) << 1
     elif self.contents & 0xFF00:
         return
     else:
         item = ItemObject.get(self.contents & 0xff)
         if item is None:
             return
         if item.rare:
             new_item = item.get_similar()
             self.contents = new_item.full_index
             return
         elif not item.buyable:
             return
         value = item.rank_price
     if random.randint(1, 20) == 20:
         value = min(65000, max(0, value))
         value = mutate_normal(value, minimum=0, maximum=65000,
                               random_degree=self.random_degree)
         self.contents = 0x8000 | (value >> 1)
         return
     if item is None:
         item = [i for i in ItemObject.every_buyable
                 if i.rank_price <= value][-1]
     new_item = item.get_similar()
     self.contents = new_item.full_index
Exemplo n.º 19
0
def randomize_battle_animations():
    raise NotImplementedError
    pointers = [1, 2, 7, 0xa, 0xb, 0xc, 0xd]
    pointers = [p + 0xd4000 for p in pointers]
    short = [0, 3, 8, 0xa, 0xc]
    longg = [2, 4, 6]
    special = [0xd, 33]
    restricted = [6]
    f = open(get_outfile(), "r+b")
    for p in pointers:
        if random.choice([True, False]):
            continue
        f.seek(p)
        value = ord(f.read(1))
        container = [l for l in [short, longg] if value in l][0]
        notcontainer = [l for l in [short, longg] if l is not container][0]
        if random.randint(1, 100) == 100:
            # use special
            value = random.choice(special)
        elif random.choice([True, False]):
            # use same type
            value = random.choice(container)
        else:
            # use different type
            candidates = [v for v in notcontainer if v not in restricted]
            value = random.choice(candidates)
        f.seek(p)
        f.write(chr(value))
    f.close()
Exemplo n.º 20
0
 def full_randomize(cls):
     if hasattr(cls, "after_order"):
         for cls2 in cls.after_order:
             if not (hasattr(cls2, "randomized") and cls2.randomized):
                 raise Exception("Randomize order violated.")
     for c in CharacterObject.every:
         c.known_spells = 0
     spells = range(0x1b)
     spells.remove(7)  # group hug
     random.shuffle(spells)
     supplemental = [0xFF] * 3
     spells = spells + supplemental
     charspells = defaultdict(list)
     while spells:
         valid = [i for i in range(5) if len(charspells[i]) < 5 or
                  (len(charspells[i]) < 6 and i != 1)]
         chosen = random.choice(valid)
         spell = spells.pop(0)
         if spell == 0xFF:
             valid = [s for s in range(0x1b) if s not in charspells[i]
                      and s != 7]  # group hug
             spell = random.choice(valid)
         charspells[chosen].append(spell)
     charspells[1].insert(random.randint(0, 5), 7)
     for l in LearnObject.every:
         l.spell = 0xFF
     for i in range(5):
         charlevels = sorted(random.sample(range(2, 20), 5))
         spells = charspells[i]
         c = CharacterObject.get(i)
         c.known_spells |= (1 << spells[0])
         for l, s in zip(charlevels, spells[1:]):
             l = LearnObject.get_by_character(i, l-2)
             l.spell = s
     cls.randomized = True
Exemplo n.º 21
0
def randomize_battle_animations():
    raise NotImplementedError
    pointers = [1, 2, 7, 0xa, 0xb, 0xc, 0xd]
    pointers = [p + 0xd4000 for p in pointers]
    short = [0, 3, 8, 0xa, 0xc]
    longg = [2, 4, 6]
    special = [0xd, 33]
    restricted = [6]
    f = open(get_outfile(), "r+b")
    for p in pointers:
        if random.choice([True, False]):
            continue
        f.seek(p)
        value = ord(f.read(1))
        container = [l for l in [short, longg] if value in l][0]
        notcontainer = [l for l in [short, longg] if l is not container][0]
        if random.randint(1, 100) == 100:
            # use special
            value = random.choice(special)
        elif random.choice([True, False]):
            # use same type
            value = random.choice(container)
        else:
            # use different type
            candidates = [v for v in notcontainer if v not in restricted]
            value = random.choice(candidates)
        f.seek(p)
        f.write(chr(value))
    f.close()
Exemplo n.º 22
0
    def mutate(self):
        if "f" not in get_flags():
            return

        if (self.index < 20 and random.randint(1, 4) == 4) or (
                self.index == 19 and BattleFormationObject.num_special < 5):
            self.become_boss()
            BattleFormationObject.num_special += 1
            return

        if self.is_boss:
            return

        if self.index >= 20:
            leaders = [f.leader for f in self.formations]
            maxrank = max([f.maxrank for f in self.formations])
            assert len(set(leaders)) == 1
            leader = leaders[0]
            candidates = [
                f for f in FormationObject.every
                if f.leader == leader and f.maxrank <= maxrank
            ]
        else:
            candidates = list(FormationObject.every)

        new_ids = [f.get_similar(candidates).index for f in self.formations]
        if len(set(new_ids)) < len(set(self.formation_ids)):
            return
        self.formation_ids = new_ids
Exemplo n.º 23
0
    def mutate(self):
        if "f" not in get_flags():
            return

        if (self.index < 20 and random.randint(1, 4) == 4) or (
                self.index == 19 and BattleFormationObject.num_special < 5):
            self.become_boss()
            BattleFormationObject.num_special += 1
            return

        if self.is_boss:
            return

        if self.index >= 20:
            leaders = [f.leader for f in self.formations]
            maxrank = max([f.maxrank for f in self.formations])
            assert len(set(leaders)) == 1
            leader = leaders[0]
            candidates = [f for f in FormationObject.every
                          if f.leader == leader and f.maxrank <= maxrank]
        else:
            candidates = list(FormationObject.every)

        new_ids = [f.get_similar(candidates).index for f in self.formations]
        if len(set(new_ids)) < len(set(self.formation_ids)):
            return
        self.formation_ids = new_ids
Exemplo n.º 24
0
    def become_boss(self):
        flamerus_rank = MonsterObject.get(0x4a).rank
        battlefields = [bf for bf in BattleFormationObject.ranked
                        if bf.index < 20]
        my_index = battlefields.index(self)
        candidates = [m for m in MonsterObject.ranked
                      if m.rank >= flamerus_rank]
        new_index = int(round(my_index * (len(candidates) / 20.0)))
        new_index = mutate_normal(new_index, minimum=0,
                                  maximum=len(candidates)-1)
        leader = candidates[new_index]
        candidates = [m for m in MonsterObject.ranked
                      if m.rank < leader.rank]
        max_index = len(candidates)-1
        follow_index = random.randint(random.randint(0, max_index), max_index)
        follower = candidates[follow_index].index
        if random.randint(0, max_index) >= follow_index:
            follow2_index = random.randint(
                random.randint(max_index-follow_index, max_index), max_index)
            follower2 = candidates[follow2_index].index
            new_ids = [follower, leader.index, follower2]
        else:
            new_ids = [leader.index, follower, 0xFF]
        f = FormationObject.get_unused()
        f.special_boss = True
        f.enemy_ids = new_ids
        self.formation_ids = [f.index] * 3
        f.mutated = True
        br = BattleRoundsObject.get(self.index)
        br.num_rounds = 1
        br.mutated = True

        if "t" not in get_flags():
            return
        br2 = BattleRewardObject.get(self.index)
        br2.reward = 0x4000
        done_items = [t.reward & 0xFF for t in BattleRewardObject.every
                      if hasattr(t, "mutated") and t.mutated
                      and t.reward & 0x4000]
        if TreasureIndexObject.well_hidden:
            value = random.choice(sorted(TreasureIndexObject.well_hidden))
            TreasureIndexObject.well_hidden.remove(value)
        else:
            value = random.choice([i for i in DESIRABLE_ITEMS
                                   if i != 0x14 and i not in done_items])
        br2.reward |= value
        br2.mutated = True
Exemplo n.º 25
0
 def bit_random_add(self, attr, rate=0.5):
     size = self.get_bit_width(attr)
     while random.random() <= rate:
         mask = 1 << random.randint(0, size-1)
         value = getattr(self, attr)
         if value & mask:
             break
         setattr(self, attr, value | mask)
Exemplo n.º 26
0
    def intershuffle(cls):
        candidates = sorted(
            [jco for jco in JobCrystalObject.every if jco.intershuffle_valid],
            key=lambda jco: (jco.ability_ap_rank, jco.signature))
        shuffled = []
        while candidates:
            max_index = len(candidates) - 1
            index = random.randint(0, max_index)
            degree = JobCrystalObject.random_degree**0.25
            if degree <= 0.5:
                degree = degree * 2
                a, b = 0, index
            else:
                degree = (degree - 0.5) * 2
                a, b = index, max_index
            index = int(round((a * (1 - degree)) + (b * degree)))
            index = random.randint(0, index)
            chosen = candidates[index]
            shuffled.append(chosen)
            candidates.remove(chosen)

        candidates = sorted(shuffled,
                            key=lambda jco: (jco.rank, jco.signature))
        if 'GBA' not in get_global_label():
            assert len(candidates) == len(shuffled) == 21
        else:
            assert len(candidates) == len(shuffled) == 25
        for c, s in zip(candidates, shuffled):
            c.crystal_index = s.old_data["crystal_index"]

        freelancer = [jco for jco in candidates if jco.is_freelancer][0]
        fight_crystals = [jco for jco in shuffled if jco.has_fight_command]
        if freelancer not in fight_crystals:
            assert not freelancer.has_fight_command
            chosen = fight_crystals[0]
            freelancer.crystal_index, chosen.crystal_index = (
                chosen.crystal_index, freelancer.crystal_index)
        assert freelancer.has_fight_command

        if 'r' in get_flags():
            chance = int(RemoveJobs.random_degree * 100)
            print('Removing jobs ({}% chance)...'.format(chance))
            for c in candidates:
                if random.random() < RemoveJobs.random_degree:
                    c.crystal_index = freelancer.crystal_index
Exemplo n.º 27
0
    def shuffle(self):
        spells = [s for s in self.spell_queue if s != 0xFF]
        if spells:
            length = random.randint(len(set(spells)), 8)
            temp = sorted(set(spells))
            while len(temp) < length:
                temp.append(random.choice(spells))
            random.shuffle(temp)
            self.spell_queue = temp

        skills = [s for s in self.skill_queue if s != 0xFF]
        if skills:
            length = random.randint(len(set(skills)), 4)
            temp = sorted(set(skills))
            while len(temp) < length:
                temp.append(random.choice(skills))
            random.shuffle(temp)
            self.skill_queue = temp
Exemplo n.º 28
0
 def bit_random_remove(self, attr, rate=0.5):
     size = self.get_bit_width(attr)
     while random.random() <= rate:
         mask = 1 << random.randint(0, size-1)
         mask = mask ^ ((2**size)-1)
         value = getattr(self, attr)
         if value == value & mask:
             break
         setattr(self, attr, value & mask)
Exemplo n.º 29
0
 def mutate(self):
     value = mutate_normal(self.price, minimum=0, maximum=65000,
                           random_degree=self.random_degree)
     value = value * 2
     power = 0
     while value > 100:
         value /= 10
         power += 1
     value = (value * (10**power)) / 2
     self.price = value
     if self.equippable and not self.is_weapon:
         self.equippable = random.randint(1, 127) << 1
Exemplo n.º 30
0
    def mutate(self):
        oldstats = {}
        for key in self.mutate_attributes:
            oldstats[key] = getattr(self, key)
        super(MonsterObject, self).mutate()
        if self.is_boss:
            for (attr, oldval) in oldstats.items():
                if getattr(self, attr) < oldval:
                    setattr(self, attr, oldval)

        if self.is_boss:
            while True:
                chance = random.randint(0, 3)
                if chance == 0:
                    break
                if chance == 1:
                    self.resistances |= (1 << random.randint(4, 7))
                elif chance == 2:
                    self.immunities |= (1 << random.randint(0, 3))
                elif chance == 3:
                    weak = (1 << random.randint(4, 7))
                    if self.weaknesses_approach & weak:
                        self.weaknesses_approach ^= weak
        else:
            resistances = shuffle_bits(self.resistances >> 4, size=4)
            self.resistances = resistances << 4
            self.immunities = shuffle_bits(self.immunities, size=4)
            weak = shuffle_bits(self.weaknesses_approach >> 4, size=4)
            self.weaknesses_approach &= 0x0F
            self.weaknesses_approach |= (weak << 4)
            if random.randint(1, 3) == 3:
                self.hit_special_defense ^= 0x2
            self.hit_special_defense ^= (random.randint(0, 3) << 2)
Exemplo n.º 31
0
    def mutate(self):
        if self.rank <= 0 and self.contents:
            return

        self.reseed(salt="mut")
        partner = random.choice([
            c for c in self.every
            if c.rank > 0 and c.item_type > 0 and c.contents > 0
        ])

        value = self.rank
        if value <= 0:
            high = random.randint(0, partner.rank)
            low = random.randint(0, high)
            value = int(
                round((high * self.random_degree) +
                      (low * (1 - self.random_degree))))

        if not partner.get_bit("contains_item"):
            value = random.randint(int(round(value**0.9)), value)
            value = min(value, 65537)
            value = mutate_normal(value,
                                  1,
                                  65537,
                                  random_degree=self.random_degree)
            value = min(value, 65535)
            self.set_money_amount(value)
        else:
            partner = partner.item
            candidates = [c for c in partner.ranked if 0 < c.rank <= value]
            if not candidates:
                candidates = [c for c in partner.ranked if c.rank > 0]
                chosen = candidates[0]
            else:
                chosen = candidates[-1]
            chosen = chosen.get_similar(
                random_degree=ChestObject.random_degree)
            assert chosen.index > 0
            self.set_item(chosen)
Exemplo n.º 32
0
 def mutate(self):
     if self.index in self.restricted_indexes:
         return
     if self.multiplier <= 7 and not self.buffs:
         new_multiplier = random.randint(0, random.randint(
             0, random.randint(0, random.randint(0, 8))))
         if new_multiplier > self.multiplier:
             self.misc_multiplier = new_multiplier
     if not self.buffs and random.randint(1, 5) == 5:
         i = random.randint(0, 6)
         if i != 4 or random.randint(1, 10) == 10:
             self.ailments = (0 | 1 << i)
     if self.buffs and random.choice([True, False]):
         self.buffs |= 1 << random.randint(3, 6)
     super(MonsterAttackObject, self).mutate()
Exemplo n.º 33
0
 def mutate(self):
     if self.index == 0x42:
         # Behemoth
         return
     oldstats = {}
     for key in self.mutate_attributes:
         oldstats[key] = getattr(self, key)
     super(MonsterObject, self).mutate()
     if self.is_boss:
         for (attr, oldval) in oldstats.items():
             if getattr(self, attr) < oldval:
                 setattr(self, attr, oldval)
     for attr in ["resistances", "weaknesses", "immunities"]:
         if self.is_boss and attr == "immunities":
             continue
         value = getattr(self, attr) >> 4
         value = shuffle_bits(value, size=4) << 4
     while random.choice([True, False]):
         attr = random.choice(["resistances", "weaknesses", "immunities"])
         value = getattr(self, attr)
         if attr != "immunities" and bin(value).count("1") > 6:
             continue
         flag = (1 << random.randint(0, 7))
         if ((attr == "weaknesses" or not self.is_boss) and
                 random.randint(1, 10) == 10):
             value ^= flag
         else:
             if attr != "immunities" and bin(value).count("1") > 4:
                 continue
             value |= flag
         setattr(self, attr, value)
     self.resistances = self.resistances & 0xF0
     if self.hp < 200 or self.index in [0x43, 0x4a]:
         return
     if random.randint(1, 4) == 4:
         self.counter &= 0x0F
         newcounter = random.choice([0, 0, 0x10, 0x20, 0x40, 0x80, 0x80])
         self.counter |= newcounter
Exemplo n.º 34
0
 def mutate(self):
     if self.index == 0x42:
         # Behemoth
         return
     oldstats = {}
     for key in self.mutate_attributes:
         oldstats[key] = getattr(self, key)
     super(MonsterObject, self).mutate()
     if self.is_boss:
         for (attr, oldval) in oldstats.items():
             if getattr(self, attr) < oldval:
                 setattr(self, attr, oldval)
     for attr in ["resistances", "weaknesses", "immunities"]:
         if self.is_boss and attr == "immunities":
             continue
         value = getattr(self, attr) >> 4
         value = shuffle_bits(value, size=4) << 4
     while random.choice([True, False]):
         attr = random.choice(["resistances", "weaknesses", "immunities"])
         value = getattr(self, attr)
         if attr != "immunities" and bin(value).count("1") > 6:
             continue
         flag = (1 << random.randint(0, 7))
         if ((attr == "weaknesses" or not self.is_boss)
                 and random.randint(1, 10) == 10):
             value ^= flag
         else:
             if attr != "immunities" and bin(value).count("1") > 4:
                 continue
             value |= flag
         setattr(self, attr, value)
     self.resistances = self.resistances & 0xF0
     if self.hp < 200 or self.index in [0x43, 0x4a]:
         return
     if random.randint(1, 4) == 4:
         self.counter &= 0x0F
         newcounter = random.choice([0, 0, 0x10, 0x20, 0x40, 0x80, 0x80])
         self.counter |= newcounter
Exemplo n.º 35
0
 def mutate(self):
     value = mutate_normal(self.price,
                           minimum=0,
                           maximum=65000,
                           random_degree=self.random_degree)
     value = value * 2
     power = 0
     while value > 100:
         value /= 10
         power += 1
     value = (value * (10**power)) / 2
     self.price = value
     if self.equippable and not self.is_weapon:
         self.equippable = random.randint(1, 127) << 1
Exemplo n.º 36
0
    def mutate_stat_curve(cls, class_index, attr):
        lus = [
            lu for lu in LevelUpObject.every if lu.class_index == class_index
        ]
        assert len(lus) == 99
        lus = lus[:98]
        assert len(lus) == 98

        lus[0].reseed(salt="fullmut" + attr)
        bits = [lu.get_bit(attr) for lu in lus]
        value = len([b for b in bits if b])
        base_ratio = value / float(len(lus))
        max_ratio = max([
            cls.get_class_stat_score(i, attr) / float(len(lus))
            for i in xrange(6)
        ])
        assert max_ratio >= base_ratio
        base_ratio = mutate_normal(base_ratio,
                                   0,
                                   max_ratio,
                                   wide=False,
                                   random_degree=LevelUpObject.random_degree,
                                   return_float=True)
        remaining = list(lus)
        while remaining:
            ratio = mutate_normal(base_ratio,
                                  0,
                                  max_ratio,
                                  wide=False,
                                  random_degree=LevelUpObject.random_degree,
                                  return_float=True)
            max_index = len(remaining) - 1
            divider = random.randint(0, max_index)
            aa = remaining[:divider]
            bb = remaining[divider:]

            if len(aa) > len(bb):
                aa, bb = bb, aa
            elif len(aa) == len(bb) and random.choice([True, False]):
                aa, bb = bb, aa
            if random.choice([True, True, False]):
                to_set, remaining = aa, bb
            else:
                to_set, remaining = bb, aa

            assert len(to_set + remaining) == max_index + 1
            for lu in to_set:
                value = (random.random() < ratio)
                lu.set_bit(attr, value)
Exemplo n.º 37
0
 def rank(self):
     if not self.intershuffle_valid:
         return -1
     if self.is_magic:
         price = SpellPriceObject.get(self.value).rank
     elif self.is_item:
         price = PriceObject.get(self.value).rank
     elif self.is_monster:
         return random.randint(
             0, max(i.rank for i in PriceObject.every if not i.is_magic))
     else:
         price = self.value * (10**(self.treasure_type & 0x7))
     if not self.mutate_valid and not self.is_magic:
         price += 60000
     return price
Exemplo n.º 38
0
    def randomize(self):
        if self.index == 6:
            candidates = [jao.ability for jao in
                          JobAbilityObject.groups[self.index]
                          if jao.ability > 0x4D]
            if candidates:
                self.commands[1] = random.choice(candidates)
            return

        if self.index > 20:
            return

        old_commands = list(self.commands)
        candidates = [jao.ability for jao in
                      JobAbilityObject.groups[self.index]
                      if jao.ability <= 0x4D]
        if self.index == 20:
            candidates += [5, 2]

        redundant_groups = [
                range(0x2C, 0x32),
                range(0x32, 0x38),
                range(0x38, 0x3E),
                range(0x3E, 0x44),
                ]
        for i, ability in enumerate(self.commands):
            if not candidates:
                break
            if ability > 0 and random.randint(1, 3) == 3:
                new_command = random.choice(candidates)
                if new_command in self.commands:
                    continue
                self.commands[i] = new_command
                for rg in redundant_groups:
                    if len(set(self.commands) & set(rg)) >= 2:
                        self.commands[i] = ability
                        break
                else:
                    candidates.remove(new_command)
            if ability in candidates:
                candidates.remove(ability)
        if not set(self.commands) & set([5, 0x2b, 2]):
            self.commands = old_commands
        for rg in redundant_groups:
            if len(set(self.commands) & set(rg)) >= 2:
                assert False
Exemplo n.º 39
0
    def price_cleanup(self):
        if 'phantomthief' in get_activated_codes():
            self.price = 0

        if self.price == self.old_data['price']:
            return

        price = self.price * 2
        counter = 0
        while price >= 100:
            price = int(round(price / 10.0))
            counter += 1
            if random.randint(1, 10) == 10:
                break
        price = price * (10**counter)
        self.price = price // 2
        if self.price % 10:
            self.price += 10 - (self.price % 10)
Exemplo n.º 40
0
    def mutate(self):
        if self.is_item and self.value == 0x14:
            # Exit battlefield is fixed
            return

        self.reward = 0
        done_items = [
            t.reward & 0xFF for t in BattleRewardObject.every
            if hasattr(t, "mutated") and t.mutated and t.reward & 0x4000
        ]
        assert len(done_items) == len(set(done_items))
        if TreasureIndexObject.desirable_left:
            value = TreasureIndexObject.desirable_left.pop()
            if value == 0x14 and TreasureIndexObject.desirable_left:
                value = TreasureIndexObject.desirable_left.pop()
            if value != 0x14:
                self.reward |= 0x4000
                self.reward |= value
        if TreasureIndexObject.undesirable_left:
            remaining = [
                i for i in TreasureIndexObject.undesirable_left
                if i not in BROKEN_ITEMS
            ]
            if remaining:
                value = remaining.pop()
                self.reward |= 0x4000
                self.reward |= value
                TreasureIndexObject.undesirable_left.remove(value)

        if self.reward == 0:
            rewardtype = random.choice(["xp", "xp", "item", "gp"])
            if rewardtype == "item":
                self.reward |= 0x4000
                self.reward |= random.choice(
                    sorted(set(DESIRABLE_ITEMS + UNDESIRABLE_ITEMS)))
            else:
                if rewardtype == "xp":
                    self.reward |= 0x8000
                self.reward |= random.randint(1, 0x3FF)

        if self.reward & 0x4000 and (self.reward & 0xFF) in done_items:
            self.reward = 0
            return self.mutate()
Exemplo n.º 41
0
    def mutate(self):
        if self.is_item and self.value == 0x14:
            # Exit battlefield is fixed
            return

        self.reward = 0
        done_items = [t.reward & 0xFF for t in BattleRewardObject.every
                      if hasattr(t, "mutated") and t.mutated
                      and t.reward & 0x4000]
        assert len(done_items) == len(set(done_items))
        if TreasureIndexObject.desirable_left:
            value = TreasureIndexObject.desirable_left.pop()
            if value == 0x14 and TreasureIndexObject.desirable_left:
                value = TreasureIndexObject.desirable_left.pop()
            if value != 0x14:
                self.reward |= 0x4000
                self.reward |= value
        if TreasureIndexObject.undesirable_left:
            remaining = [i for i in TreasureIndexObject.undesirable_left
                         if i not in BROKEN_ITEMS]
            if remaining:
                value = remaining.pop()
                self.reward |= 0x4000
                self.reward |= value
                TreasureIndexObject.undesirable_left.remove(value)

        if self.reward == 0:
            rewardtype = random.choice(["xp", "xp", "item", "gp"])
            if rewardtype == "item":
                self.reward |= 0x4000
                self.reward |= random.choice(
                    sorted(set(DESIRABLE_ITEMS + UNDESIRABLE_ITEMS)))
            else:
                if rewardtype == "xp":
                    self.reward |= 0x8000
                self.reward |= random.randint(1, 0x3FF)

        if self.reward & 0x4000 and (self.reward & 0xFF) in done_items:
            self.reward = 0
            return self.mutate()
Exemplo n.º 42
0
 def mutate(self):
     if bin(self.equippable).count('1') > 3:
         self.equippable = random.randint(1, 127) << 1
Exemplo n.º 43
0
    def mutate(self):
        if not self.unused:
            self.find_unused()
        old_ids = list(self.enemy_ids)
        if self.is_boss:
            boss = self.leader
            boss_index = boss.index
            if boss_index == 0x50:
                return
            new = []
            upper = self.leader.rank
            for e in self.enemy_ids:
                if e == boss_index:
                    continue
                if e == 0xFF and random.choice([True, False]):
                    continue
                if e == 0xFF:
                    lower = 0
                else:
                    lower = MonsterObject.get(e).rank
                candidates = [m for m in MonsterObject.ranked
                              if lower <= m.rank < upper
                              and m.index not in self.banned_bosses]
                if not candidates:
                    return
                upper_index = max(len(candidates)-2, 0)
                index = random.randint(0, upper_index)
                index = random.randint(index/2, index)
                chosen = candidates[index]
                upper = min(upper, chosen.rank)
                new.append(chosen.index)
            if len(new) == 2:
                new = [new[0], boss_index, new[1]]
            else:
                new = new + [boss_index]
            while len(new) < 3:
                new += [0xFF]
            self.enemy_ids = new
            return

        if len(self.enemies) <= 1:
            return

        for i, e in enumerate(self.enemies):
            if len(self.enemies) >= 2 and i == 1:
                continue
            elif len(self.enemies) == 1:
                continue
            new = e.get_similar()
            if new.index in self.banned_bosses:
                continue
            if new in self.done_bosses and random.randint(1, 10) != 10:
                continue
            self.enemy_ids[i] = new.index
            if new.is_boss:
                self.done_bosses.add(new)

        new_tuple = sorted(tuple(self.enemy_ids))
        if new_tuple == sorted(tuple(old_ids)):
            return
        for f in FormationObject.every:
            if f.index == self.index:
                continue
            if sorted(tuple(f.enemy_ids)) == new_tuple:
                self.enemy_ids = old_ids
                break
Exemplo n.º 44
0
 def mutate(self):
     super(WeaponObject, self).mutate()
     if random.randint(1, 3) == 3:
         element = (1 << random.randint(3, 7))
         self.element |= element