Ejemplo n.º 1
0
class Main(BaseGbaHack):
    BATTLE_CARDS_PAGE_LENGTH = 12
    BATTLE_CARDS_PAGE_TOTAL = 47

    def __init__(self):
        super().__init__()
        self._global = Global(0, self.handler)
        self._global.battle_cards_offset = 0

    def render_main(self):
        with Group("global", "全局", self._global):
            ModelInput("hp")
            ModelInput("hpmax")
            ModelInput("cpmax")
            ModelInput("exp")
            ModelInput("mp")
            ModelInput("dark")
            ModelInput("atk")
            ModelInput("battle_hp")
            ModelInput("battle_hpmax")
            ModelCheckBox("riku_enable")

        self.battle_cards_group = Group("battle_cards", "战斗卡片", self._global, cols=4)
        self.lazy_group(self.battle_cards_group, self.render_battle_cards)

    def render_battle_cards(self):
        with ModelSelect.choices_cache:
            for i in range(self.BATTLE_CARDS_PAGE_LENGTH):
                ModelSelect("battle_cards.%d+battle_cards_offset.card_type" % i, "", choices=BATTLE_CARDS)
                ModelSelect("battle_cards.%d+battle_cards_offset.card_value" % i, "",
                    choices=map(str, range(10)))

        with Group.active_group().footer:
            Pagination(self.on_battle_cards_page, self.BATTLE_CARDS_PAGE_TOTAL)

    def on_battle_cards_page(self, page):
        self._global.battle_cards_offset = (page - 1) * self.BATTLE_CARDS_PAGE_LENGTH
        self.battle_cards_group.read()
Ejemplo n.º 2
0
class GSHack(BaseGbaHack):
    SKILLS_PAGE_LENGTH = 5
    SKILLS_PAGE_TOTAL = 7

    def __init__(self):
        super().__init__()
        self._global = self.models.Global(0, self.handler)
        self.person = self.models.Person(0, self.handler)
        self.person.skills_offset = 0

    def render_main(self):
        with Group("global", "全局", self._global):
            ModelInput("time", "时间")
            ModelInput("money", "金钱")
            ModelInput("get_money", "战后金钱")
            ModelInput("get_exp", "战后经验")
            ModelInput("battlein", "遇敌率")
            ModelCoordWidget("town_pos",
                             "城镇坐标",
                             length=2,
                             type=int,
                             savable=True,
                             preset=self.coords)
            ModelCoordWidget("map_pos",
                             "地图坐标",
                             length=2,
                             type=int,
                             savable=True,
                             preset=self.coords)

        self.lazy_group(Group("player", "角色", self.person, cols=4),
                        self.render_person)
        self.skills_group = Group("skills", "角色精神力", self.person)
        self.lazy_group(self.skills_group, self.render_skills)
        self.lazy_group(Group("skills", "角色物品", self.person, cols=4),
                        self.render_items)
        self.lazy_group(Group("djinnis", "角色精灵", self.person),
                        self.render_djinnis)
        self.lazy_group(StaticGroup("快捷键"), self.render_hotkeys)

    def render_person(self):
        Choice("角色", self.datasets.PERSONS, self.on_person_change)
        ModelInput("addr_hex", "地址", readonly=True)
        ModelInput("level", "等级")
        ModelInput("exp", "经验")
        ModelInput("hp", "HP")
        ModelInput("hpmax", "HP上限")
        ModelInput("ep", "EP")
        ModelInput("epmax", "EP上限")
        ModelInput("atk", "攻击")
        ModelInput("defense", "防御")
        ModelInput("speed", "速度")
        ModelInput("lucky", "好运")
        for tlabel, tname in self.datasets.ELEMENT_TYPES:
            ModelInput("%s_power" % tname, "%s力量" % tlabel)
            ModelInput("%s_defense" % tname, "%s抗性" % tlabel)

    def render_skills(self):
        with ModelSelect.choices_cache:
            for i in range(5):
                ModelSelect("skills.%d+skills_offset.value" % i,
                            "精神力",
                            choices=self.datasets.SKILLS)
        with self.skills_group.footer:
            Pagination(self.on_skills_page, self.SKILLS_PAGE_TOTAL)

    def render_items(self):
        with ModelSelect.choices_cache:
            for i in range(15):
                ModelSelect("items.%d.item" % i,
                            "物品%d" % (i + 1),
                            choices=self.datasets.ITEMS)
                ModelInput("items.%d.count" % i, "数量")

    def render_djinnis(self):
        for (tlable, tname), (labels,
                              helps) in zip(self.datasets.ELEMENT_TYPES,
                                            self.datasets.DJINNIS):
            ModelFlagWidget("djinni_%s" % tname,
                            "%s精灵" % tlable,
                            labels=labels,
                            helps=helps,
                            checkbtn=True,
                            cols=4)
            ModelFlagWidget("djinni_%s_on" % tname,
                            "附身",
                            labels=labels,
                            helps=helps,
                            checkbtn=True,
                            cols=4)
            ModelInput("djinni_%s_count" % tname,
                       "拥有数量").set_help("至少一个角色精灵数量大于0才会显示精灵菜单")
            ModelInput("djinni_%s_on_count" % tname, "附身数量")

    def render_hotkeys(self):
        ui.Text("左移: alt+left\n"
                "右移: alt+right\n"
                "上移: alt+up\n"
                "下移: alt+right\n"
                "恢复HP: alt+h")

    def get_hotkeys(self):
        this = self.weak
        return (
            (VK.MOD_ALT, VK.LEFT, this.move_left),
            (VK.MOD_ALT, VK.RIGHT, this.move_right),
            (VK.MOD_ALT, VK.UP, this.move_up),
            (VK.MOD_ALT, VK.DOWN, this.move_down),
            (VK.MOD_ALT, VK.H, this.pull_through),
        )

    def on_person_change(self, lb):
        self.person.addr = self.PERSON_ADDR_START + lb.index * self.models.Person.SIZE

    def persons(self):
        person = self.models.Person(0, self.handler)
        for i in range(len(self.datasets.PERSONS)):
            person.addr = self.PERSON_ADDR_START + i * self.models.Person.SIZE
            yield person

    def on_skills_page(self, page):
        self.person.skills_offset = (page - 1) * self.SKILLS_PAGE_LENGTH
        self.skills_group.read()

    def move_left(self):
        if self._global.map_x is 0:
            self._global.town_x -= 10
        else:
            self._global.map_x -= 10

    def move_right(self):
        if self._global.map_x is 0:
            self._global.town_x += 10
        else:
            self._global.map_x += 10

    def move_up(self):
        if self._global.map_x is 0:
            self._global.town_y -= 10
        else:
            self._global.map_y -= 10

    def move_down(self):
        if self._global.map_x is 0:
            self._global.town_y += 10
        else:
            self._global.map_y += 10

    def pull_through(self):
        for person in self.persons():
            person.hp = person.hpmax
Ejemplo n.º 3
0
class FeHack(BaseGbaHack):
    TRAIN_ITEMS_PAGE_LENGTH = 10
    TRAIN_ITEMS_PAGE_TOTAL = 10

    def __init__(self):
        super().__init__()
        self._global = self.models.Global(0, self.handler)
        self._global.train_items_offset = 0
        self._person_ins = self.models.Person(0, self.handler)

    def render_main(self):
        with Group("global", "全局", self._global):
            self.render_global()

        self.lazy_group(Group("player", "角色", self._person, cols=4),
                        self.render_char)
        self.lazy_group(Group("items", "角色物品", self._person, cols=4),
                        self.render_char_items)
        self.lazy_group(Group("support", "角色支援", self._person, cols=4),
                        self.render_char_support)

        self.train_items_group = Group("train_items",
                                       "运输队",
                                       self._global,
                                       cols=4)
        self.lazy_group(self.train_items_group, self.render_train_items)

    def render_global(self):
        ModelInput("money", "金钱")
        ModelInput("turns", "回合")
        ModelInput("random", "乱数").set_help("设成0: 招招命中、必杀、贯通等,升级7点成长")
        ModelSelect("chapter", "章节", choices=self.datasets.CHAPTERS)
        ModelCheckBox("inf_move", "无限行动")
        ModelCheckBox("item_count_keep", "武器耐久度不减")
        ModelCheckBox("proficiency_max", "武器熟练度最大")
        ModelCheckBox("ability_up_1", "全能力成长1点")
        ModelCheckBox("ability_up_2", "全能力成长2点")
        ModelCheckBox("got_100exp", "战后升级")
        ModelCheckBox("support_quickly", "好感度快速提升")

    def render_char(self):
        datasets = self.datasets
        ModelInput("addr_hex", "R键地址", readonly=True).set_help("R键人物详情中人物属性")
        ModelInput("no", "序号")
        ModelSelect("prof",
                    "职业",
                    choices=datasets.PROFESSIONS,
                    values=datasets.PROFESSION_VALUES)
        ModelInput("level", "等级")
        ModelInput("exp", "经验")
        ModelCheckBox("moved", "已行动", enable=1, disable=0)
        ModelInput("posx", "X坐标")
        ModelInput("posy", "Y坐标")
        ModelInput("hpmax", "HP最大值")
        ModelInput("hp", "HP")
        ModelInput("power", "力量")
        ModelInput("skill", "技术")
        ModelInput("speed", "速度")
        ModelInput("defense", "守备")
        ModelInput("magicdef", "魔防")
        ModelInput("lucky", "幸运")
        ModelInput("physical_add", "体格+")
        ModelInput("move_add", "移动+")
        ModelSelect("status", "状态种类", choices=datasets.STATUS)
        ModelInput("status_turn", "状态持续")
        for i, label in enumerate(("剑", "枪", "斧", "弓", "杖", "理", "光", "暗")):
            ModelInput("proficiency.%d" % i, "%s熟练度" %
                       label).set_help("E级:1 D级:31 C级:71 B级:121 A级:181 S级:251")

    def render_char_items(self):
        datasets = self.datasets
        with ModelSelect.choices_cache:
            for i in range(5):
                ModelSelect("items.%d.item" % i,
                            "物品%d" % (i + 1),
                            choices=datasets.ITEMS)
                ModelInput("items.%d.count" % i, "数量")

    def render_char_support(self):
        for i in range(self._person_ins.support.length):
            ModelInput("support.%d" % i, "好感度%d" %
                       (i + 1)).set_help('80~160: C, 160~240: B, 240~255: A')

    def render_train_items(self):
        datasets = self.datasets
        with ModelSelect.choices_cache:
            for i in range(10):
                ModelSelect("train_items.%d+train_items_offset.item" % i,
                            "",
                            choices=datasets.ITEMS)
                ModelInput("train_items.%d+train_items_offset.count" % i, "数量")
        with Group.active_group().footer:
            Pagination(self.on_train_items_page, self.TRAIN_ITEMS_PAGE_TOTAL)

    def get_hotkeys(self):
        return (
            (0, VK.H, self.pull_through),
            (0, VK.M, self.continue_move),
            (0, VK.G, self.move_to_cursor),
            (0, VK.T, self.toggle_random),
            (0, VK.R, self.reload_ammo),
            (0, VK.N, self.remove_weapon),
            (0, VK.LEFT, self.move_left),
            (0, VK.RIGHT, self.move_right),
            (0, VK.UP, self.move_up),
            (0, VK.DOWN, self.move_down),
            (0, VK._0, self.hp_zero),
            (0, VK.DELETE, self.delete_unit),
        )

    def _person(self):
        person_addr = self._global.person_addr
        if person_addr and (person_addr & 0xFFFF0000 == 0x02020000):
            self._person_ins.addr = person_addr
        if self._person_ins.addr:
            return self._person_ins

    person = property(_person)

    def pull_through(self):
        """再移动"""
        self.person.set_with('hp', 'hpmax')

    def continue_move(self):
        """再移动"""
        self.person.moved = False

    def move_to_cursor(self):
        person = self.person
        _global = self._global
        person.posx = _global.curx
        person.posy = _global.cury

    def toggle_random(self):
        """切换乱数"""
        last_random = self._global.random
        if last_random != 0:
            self.last_random = last_random
            self._global.random = 0
        else:
            self._global.random = self.last_random

    def reload_ammo(self):
        """恢复耐久"""
        for item in self._person().items:
            if not item.item:
                break
            item.count = 99

    def remove_weapon(self):
        """移除物品"""
        for item in self._person().items:
            if not item.item:
                break
            item.value = 0

    def move_left(self):
        self.person.posx -= 1

    def move_right(self):
        self.person.posx += 1

    def move_up(self):
        self.person.posy -= 1

    def move_down(self):
        self.person.posy += 1

    def hp_zero(self):
        self.person.hp = 1

    def delete_unit(self):
        unit = self.person
        if unit.no >= 64:
            unit.unkonw_ptr = 0
            unit.prof = 0
            unit.moved = 1
            unit.hp = 0

    def on_train_items_page(self, page):
        self._global.train_items_offset = (page -
                                           1) * self.TRAIN_ITEMS_PAGE_LENGTH
        self.train_items_group.read()
Ejemplo n.º 4
0
class FeHack(BaseNdsHack):
    TRAIN_ITEMS_PAGE_LENGTH = 10
    TRAIN_ITEMS_PAGE_TOTAL = 20

    def __init__(self):
        super().__init__()
        self._global = self.models.Global(0, self.handler)
        self._global.train_items_offset = 0
        self._person_ins = self.models.Person(0, self.handler)
        self.item_index = 1

    def render_main(self):
        datasets = self.datasets
        weak = self.weak

        with Group("global", "全局", self._global, cols=4):
            ModelInput("money", "金钱", instance=weak._config)
            ModelInput("turns", "回合")
            ModelCheckBox("ourturn", "总是我方回合")
            ModelCheckBox("control_enemy", "可控制敌人")
            ModelCheckBox("upgrade_max", "升级能力值最大")
            ModelCheckBox("upgrade_all", "升级全能力提升")
            ModelCheckBox("lv1_can_transfer", "Lv1即可转职")
            ModelCheckBox("can_train", "都可用运输队")
            ModelCheckBox("can_visit", "都可访问村庄")
            ModelCheckBox("can_holddown", "都可压制")
            ModelCheckBox("use_enemy_prof", "使用敌专用兵种不死机")
            ModelCheckBox("infinite_refine", "武器屋炼成无限次")
            ModelCheckBox("item_consume", "道具耐久不减")
            ModelCheckBox("enemy_item_drop", "敌人全道具掉落")
            ModelSelect("exp_rate",
                        "经验值倍数",
                        choices=datasets.RATE,
                        values=datasets.EXP_RATE_VALUES)
            ModelSelect("pro_rate",
                        "熟练度倍数",
                        choices=datasets.RATE,
                        values=datasets.PRO_RATE_VALUES)
            # ModelInput("random", "乱数").set_help("设成0: 招招命中、必杀、贯通等,升级7点成长")
            # ModelSelect("chapter", "章节", choices=datasets.CHAPTERS)

        self.lazy_group(Group("config", "配置", weak._config, cols=4),
                        self.render_config)
        self.lazy_group(Group("player", "角色", weak._person, cols=4),
                        self.render_person)
        self.lazy_group(Group("items", "角色物品", weak._person, cols=4),
                        self.render_items)
        self.lazy_group(Group("iteminfos", "武器属性", weak._iteminfo),
                        self.render_iteminfos)

        self.train_items_group = Group("train_items",
                                       "运输队",
                                       self._global,
                                       cols=4)
        self.lazy_group(self.train_items_group, self.render_train_items)

    def render_config(self):
        datasets = self.datasets
        ModelSelect("difficulty",
                    "难易度",
                    choices=datasets.DIFFICULTY,
                    values=datasets.DIFFICULTY_VALUES)
        if self.models.Config.character_gender:
            ModelSelect("character_gender",
                        "主人公性别",
                        choices=datasets.CHARACTER_GENDER)
            ModelSelect("character_hair_style",
                        "主人公发色",
                        choices=datasets.CHARACTER_HAIR_STYLE)
            ModelSelect("character_hair_color",
                        "主人公发型",
                        choices=datasets.CHARACTER_HAIR_COLOR)
            ModelSelect("character_eye",
                        "主人公眼睛",
                        choices=datasets.CHARACTER_EYE)
            ModelSelect("character_cloth",
                        "主人公服装",
                        choices=datasets.CHARACTER_CLOTH)

    def render_person(self):
        datasets = self.datasets
        ModelInput("addr_hex", "地址", readonly=True)
        ModelInput("no", "序号")
        ModelSelect("prof",
                    "职业",
                    choices=datasets.PROFESSIONS,
                    values=datasets.PROFESSION_VALUES)
        ModelInput("level", "等级")
        ModelInput("exp", "经验")
        ModelCheckBox("moved", "已行动", enable=1, disable=0)
        ModelInput("posx", "X坐标")
        ModelInput("posy", "Y坐标")
        ModelInput("hpmax", "HP上限+")
        ModelInput("hp", "HP")
        ModelInput("power", "力量+")
        ModelInput("magic", "魔力+")
        ModelInput("skill", "技术+")
        ModelInput("speed", "速度+")
        ModelInput("defense", "守备+")
        ModelInput("magicdef", "魔防+")
        ModelInput("lucky", "幸运+")
        ModelInput("move_add", "移动+")
        # ModelSelect("status", "状态种类", choices=datasets.STATUS)
        # ModelInput("status_turn", "状态持续")
        for i, label in enumerate(("剑", "枪", "斧", "弓", "书", "杖")):
            ModelInput("proficiency.%d" % i,
                       "%s熟练度+" % label).set_help(datasets.PROFICIENCY_HINT)

    def render_items(self):
        datasets = self.datasets
        with ModelSelect.choices_cache:
            for i in range(5):
                ModelSelect("items.%d.item" % i,
                            "物品%d" % (i + 1),
                            choices=datasets.ITEMS)
                ModelInput("items.%d.count" % i, "数量")

    def render_iteminfos(self):
        datasets = self.datasets
        Choice("物品", datasets.ITEMS, self.on_item_change)
        Label("复制属性")
        with ui.Horizontal(className="fill"):
            self.copy_iteminfo_view = ui.Choice(className="fill",
                                                choices=datasets.ITEMS)
            ui.Button("复制", onclick=self.copy_iteminfo)
        ModelInput("addr_hex", "地址", readonly=True)
        ModelInput("name_ptr", "名称指针", hex=True)
        ModelInput("desc_ptr", "介绍文本", hex=True)
        ModelInput("icon", "图标序号")
        ModelSelect("type", "类型", choices=datasets.WEAPONTYPES)
        ModelInput("level", "要求熟练度", hex=True,
                   size=1).set_help(datasets.PROFICIENCY_HINT)
        ModelInput("power", "威力")
        ModelInput("hit", "命中")
        ModelInput("kill", "必杀")
        ModelInput("weight", "重量")
        ModelInput("range_min", "最小射程")
        ModelInput("range_max", "最大射程")
        ModelInput("move_add", "移动+")
        ModelInput("hp_add", "HP+")
        ModelInput("power_add", "力量+")
        ModelInput("magic_add", "魔力+")
        ModelInput("skill_add", "技巧+")
        ModelInput("speed_add", "速度+")
        ModelInput("lucky_add", "幸运+")
        ModelInput("defense_add", "防御+")
        ModelInput("magicdef_add", "魔防+")

        i = 0
        for item in datasets.ITEM_ATTRS:
            hint, labels = item
            i += 1
            ModelFlagWidget("attr%d" % i, hint or "属性%d" % i, labels=labels)

    def render_train_items(self):
        datasets = self.datasets
        with ModelSelect.choices_cache:
            for i in range(10):
                ModelSelect("train_items.%d+train_items_offset.item" % i,
                            "",
                            choices=datasets.ITEMS)
                ModelInput("train_items.%d+train_items_offset.count" % i, "数量")
        with Group.active_group().footer:
            Pagination(self.on_train_items_page, self.TRAIN_ITEMS_PAGE_TOTAL)

    def get_hotkeys(self):
        this = self.weak
        return (
            (VK.MOD_ALT, VK.M, this.continue_move),
            (VK.MOD_ALT, VK.G, this.move_to_cursor),
            (VK.MOD_ALT, VK.LEFT, this.move_left),
            (VK.MOD_ALT, VK.RIGHT, this.move_right),
            (VK.MOD_ALT, VK.UP, this.move_up),
            (VK.MOD_ALT, VK.DOWN, this.move_down),
        )

    def _person(self):
        person_addr = self._global.person_addr
        if person_addr:
            self._person_ins.addr = person_addr
            return self._person_ins

    person = property(_person)

    def _config(self):
        return self._global.config

    def on_item_change(self, lb):
        self.item_index = lb.index

    def _iteminfo(self):
        if self.item_index > 0:
            return self._global.iteminfos[self.item_index - 1]

    def copy_iteminfo(self, _=None):
        index = self.copy_iteminfo_view.index
        if index > 0:
            item_from = self._global.iteminfos[index - 1]
            self.handler.write(
                self._global.iteminfos.addr_at(self.item_index - 1),
                item_from.to_bytes())

    def continue_move(self):
        """再移动"""
        self.person.moved = False

    def move_to_cursor(self):
        person = self.person
        _global = self._global
        person.posx = _global.curx
        person.posy = _global.cury

    def move_left(self):
        self.person.posx -= 1

    def move_right(self):
        self.person.posx += 1

    def move_up(self):
        self.person.posy -= 1

    def move_down(self):
        self.person.posy += 1

    def on_train_items_page(self, page):
        self._global.train_items_offset = (page -
                                           1) * self.TRAIN_ITEMS_PAGE_LENGTH
        self.train_items_group.read()
Ejemplo n.º 5
0
class PMHack(BaseGbaHack):
    BACKPACK_PAGE_LENGTH = 10

    def __init__(self):
        super().__init__()
        self._global_ins = None
        self._pokemon_ins = models.Pokemon(0, self.handler)
        self.active_pokemon_index = 0
        self.active_pokemon_ins = None

    def render_main(self):
        with Group("global", "全局", self._global, horizontal=False):
            self.render_global()

        self.lazy_group(Group("shop", "商店购物", self._global), self.render_shop)
        self.backpack_group = Group("store",
                                    "背包",
                                    self._global,
                                    hasheader=True,
                                    cols=4)
        self.lazy_group(self.backpack_group, self.render_backpack)
        self.pokemon_group = StaticGroup("宝可梦")
        self.lazy_group(self.pokemon_group, self.render_pokemon)

    def render_global(self):
        datasets = self.datasets

        ModelInput("money", "金钱", spin=True)
        ModelInput("coin", "游戏币", spin=True)
        ModelInput("dust", "宝石版火山灰", spin=True)
        ModelInput("spray_time", "喷雾剂剩余步数", spin=True)
        ModelInput("safari_time", "狩猎区剩余步数", spin=True)
        ModelInput("battle_points_current", "战斗点数(仅绿宝石)", spin=True)
        ModelInput("battle_points_trainer_card", "训练员卡上的战斗点数(仅绿宝石)", spin=True)

        ModelSelect("area",
                    "地点瞬移",
                    choices=datasets.AREA_LABELS,
                    values=datasets.AREA_VALUES)
        ModelSelect("furniture_purchase", "家具购买", choices=datasets.FURNITURES)
        ModelSelect("appearance", "性别外形", choices=datasets.APPEARANCE)
        # ModelSelect("wild_pokemon", "遇到精灵", choices=datasets.POKEMONS)

    def render_shop(self):
        datasets = self.datasets
        with ModelSelect.choices_cache:
            for i in range(8):
                ModelSelect("store.%d.item" % i,
                            "商品%d" % (i + 1),
                            choices=datasets.ITEMS)

    def render_backpack(self):
        datasets = self.datasets
        with self.backpack_group.header:
            ui.RadioBox("类型",
                        className="fill",
                        choices=datasets.BACKPACK_LABELS,
                        onselect=self.on_backpack_swith)
        for i in range(self.BACKPACK_PAGE_LENGTH):
            ModelSelect("backpack_items.%d+backpack_offset.item" % i,
                        "",
                        choices=datasets.ITEMS)
            ModelInput("backpack_items.%d+backpack_offset.quantity" % i, "数量")
        with self.backpack_group.footer:
            self.backpack_pageview = Pagination(self.on_backpack_page,
                                                self.BACKPACK_PAGE_LENGTH)

    def render_pokemon(self):
        # pokemon = self.weak._pokemon
        active_pokemon = self._active_pokemon

        ui.RadioBox("带着的宝可梦",
                    className="expand",
                    choices=tuple(str(i) for i in range(1, 7)),
                    onselect=self.on_active_pokemo_swith)

        with Groups(None, self.weak.onNotePageChange):
            with Group("basic", "基本", active_pokemon):
                ModelInput("breedInfo.bIntimate", "亲密度", spin=True, max=255)
                ModelSelect("breedInfo.wBreed",
                            "种族",
                            choices=self.datasets.BREED_NAMES)
                ModelInput("Header.dwChar", "性格值", hex=True)
                ModelInput("Header.dwID", "ID", hex=True)
                ModelSelect("personality",
                            "性格",
                            choices=self.datasets.PERSONALITYS,
                            onselect=self.on_personality_select)
                ui.Text("性格描述", className="vcenter")
                self.personality_desc = ui.Text("", className="vcenter")
                ModelSelect("breedInfo.wItem",
                            "手持道具",
                            choices=self.datasets.ITEMS)
                ModelInput("breedInfo.dwExp", "经验值")
            with Group("basic", "能力", active_pokemon):
                pass
            with Group("basic", "技能", active_pokemon):
                pass
            with Group("basic", "缎带", active_pokemon):
                pass
            with Group("basic", "其它", active_pokemon):
                pass

        with ui.Horizontal(className="expand"):
            ui.Button("读入",
                      className="btn_sm",
                      onclick=self.read_active_pokemon)
            ui.Button("写回",
                      className="btn_sm",
                      onclick=self.write_active_pokemon)

    def onattach(self):
        super().onattach()
        rom_title = self.handler.getRomTitle()

        item = models.GAME_VERSON.get(rom_title, None)
        if item is None and rom_title == "YJencrypted":
            szGameVersion = self.handler.read(0x08000108, bytes, 32).decode()
            item = models.GAME_ENCRYPTED.get(szGameVersion, None)

        if item:
            self._global_ins = item[0](0, self.handler)
            self.pm_version = item[1]
            self.lang = item[2]
            # 初始化一些背包参数
            self._global_ins.backpack_offset = 0

    def _global(self):
        return self._global_ins

    def read_active_pokemons(self):
        pokemons = self._global_ins.active_pokemon.tolocal()
        for pokemon in pokemons.content:
            pokemon.pmStruct.attach()
            pokemon.pmStruct.Decode()
        return pokemons

    def read_active_pokemon(self, _=None):
        active_pokemon = self._global_ins.active_pokemon.content[
            self.active_pokemon_index]
        self.active_pokemon_ins = pokemon = active_pokemon.pmStruct.tolocal()
        pokemon.attach()
        pokemon.Decode()
        return pokemon

    def write_active_pokemon(self, _=None):
        pokemon = self.active_pokemon_ins
        if pokemon:
            temp = pokemon.tolocal()
            temp.bEncoded = False
            temp.Encode()
            self._global_ins.active_pokemon.content[
                self.active_pokemon_index].pmStruct = temp

    def _active_pokemon(self):
        return self.active_pokemon_ins or self.read_active_pokemon()

    def _active_pokemon_breed(self):
        """选中的宝可梦的种族数据"""
        pokemon = self._active_pokemon()
        if pokemon:
            breed = pokemon.breedInfo.wBreed
            if breed < BREED_COUNT:
                return self._global_ins.breed_list[breed]

    def _active_pokemon_exp_list(self):
        """选中的宝可梦的种族EXP列表"""
        breed_entry = self._active_pokemon_breed()
        if breed_entry:
            exptype = breed_entry.bExpType
            return self._global_ins.exp_list[exptype]

    # pokemon = property(_pokemon)
    # active_pokemons = property(_active_pokemons)

    def on_backpack_page(self, page):
        """背包物品切换页"""
        self._global_ins.backpack_offset = (page -
                                            1) * self.BACKPACK_PAGE_LENGTH
        self.backpack_group.read()

    def on_backpack_swith(self, view):
        self._global_ins.backpack_type = self.datasets.BACKPACK_KEYS[
            view.index]
        self.backpack_pageview.asset_total(
            self._global_ins.backpack_items.length, self.BACKPACK_PAGE_LENGTH)
        self.backpack_group.read()

    def on_active_pokemo_swith(self, view):
        self.active_pokemon_index = view.index
        self.read_active_pokemon()
        self.pokemon_group.read()

    def on_personality_select(self, view):
        personality = view.index
        b = [1, 1, 1, 1, 1]
        b[personality // 5] += 1
        b[personality % 5] -= 1
        sz = ("-", " ", "+")
        desc = "攻击:{}防御:{}敏捷:{}特攻:{}特防:{}".format(*(sz[i] for i in b))
        self.personality_desc.label = desc
Ejemplo n.º 6
0
class Main(BaseGbaHack):
    STORAGE_PAGE_LENGTH = 10
    STORAGE_PAGE_TOTAL = 10

    def __init__(self):
        super().__init__()
        self._global = models.Global(0, self.handler)
        self._global.storage_offset = 0
        self.person = models.Person(0, self.handler)
        self.chariot = models.Chariot(0, self.handler)

    def render_main(self):
        with Group("global", "全局", self._global):
            ModelInput("money")
            ModelInput("battlein")

        with Group("player", "角色", self.person, cols=4):
            self.render_player()

        self.lazy_group(Group("human_items", "角色装备/物品", self.person),
                        self.render_human_items)
        self.lazy_group(Group("chariot", "战车", self.chariot, cols=4),
                        self.render_chariot)
        self.lazy_group(Group("chariot_items", "战车装备/物品", self.chariot),
                        self.render_chariot_items)
        self.lazy_group(Group("special_bullets", "特殊炮弹", self.chariot, cols=4),
                        self.render_special_bullets)
        self.storage_group = Group("storage", "保管物品", self._global)
        self.lazy_group(self.storage_group, self.render_storage)
        self.lazy_group(StaticGroup("快捷键"), self.render_hotkeys)

    def render_player(self):
        Choice("角色", datasets.PERSONS, self.on_person_change)
        ModelInput("level")
        ModelInput("hp")
        ModelInput("hpmax")
        ModelInput("atk")
        ModelInput("defense")
        ModelInput("power")
        ModelInput("intelli")
        ModelInput("stamina")
        ModelInput("speed")
        ModelInput("battle")
        ModelInput("drive")
        ModelInput("fix")
        ModelInput("exp")

    def render_human_items(self):
        with ModelSelect.choices_cache:
            for i in range(self.person.equips.length):
                ModelSelect("equips.%d" % i,
                            "装备%d" % (i + 1),
                            choices=datasets.HUMAN_EQUIPS,
                            dragable=True)
            for i in range(self.person.items.length):
                ModelSelect("items.%d" % i,
                            "物品%d" % (i + 1),
                            choices=datasets.HUMAN_ITEMS,
                            dragable=True)

    def render_chariot(self):
        Choice("战车", datasets.CHARIOTS, self.on_chariot_change)
        ModelInput("sp")
        ModelInput("bullet")
        ModelInput("defense")
        ModelInput("weight")

    def render_chariot_items(self):
        with ModelSelect.choices_cache:
            for i in range(self.chariot.equips.length):
                ModelSelect("equips.%d" % i,
                            "装备%d" % (i + 1),
                            choices=datasets.CHARIOT_EQUIPS,
                            dragable=True)
            for i in range(self.chariot.items.length):
                ModelSelect("items.%d" % i,
                            "物品%d" % (i + 1),
                            choices=datasets.CHARIOT_ITEMS,
                            dragable=True)

    def render_special_bullets(self):
        with ModelSelect.choices_cache:
            for i in range(self.chariot.special_bullets.length):
                ModelSelect("special_bullets.%d" % i,
                            "炮弹%d" % (i + 1),
                            choices=datasets.SPECIAL_BULLETS,
                            dragable=True)
                ModelInput("special_bullets_count.%d" % i, "数量")

    def render_storage(self):
        choices = datasets.HUMAN_EQUIPS + datasets.HUMAN_ITEMS + datasets.CHARIOT_EQUIPS + datasets.CHARIOT_ITEMS
        values = (tuple(range(len(datasets.HUMAN_ITEMS))) + tuple(
            (0x0100 | i) for i in range(len(datasets.HUMAN_EQUIPS))) + tuple(
                (0x0200 | i)
                for i in range(len(datasets.CHARIOT_ITEMS))) + tuple(
                    (0x0300 | i) for i in range(len(datasets.CHARIOT_EQUIPS))))

        with ModelSelect.choices_cache:
            for i in range(self.STORAGE_PAGE_LENGTH):
                ModelSelect("storage.%d+storage_offset" % i,
                            "",
                            choices=choices,
                            values=values,
                            dragable=True)
        with Group.active_group().footer:
            Pagination(self.on_storage_page, self.STORAGE_PAGE_TOTAL)

    def render_hotkeys(self):
        ui.Text("左移: alt+left\n"
                "右移: alt+right\n"
                "上移: alt+up\n"
                "下移: alt+right\n"
                "恢复HP: alt+h")

    def get_hotkeys(self):
        this = self.weak
        return (
            (VK.MOD_ALT, VK.LEFT, this.move_left),
            (VK.MOD_ALT, VK.RIGHT, this.move_right),
            (VK.MOD_ALT, VK.UP, this.move_up),
            (VK.MOD_ALT, VK.DOWN, this.move_down),
            (VK.MOD_ALT, VK.H, this.pull_through),
        )

    def on_person_change(self, lb):
        self.person.addr = lb.index * models.Person.SIZE

    def on_chariot_change(self, lb):
        self.chariot.addr = lb.index * models.Chariot.SIZE

    def on_storage_page(self, page):
        self._global.storage_offset = (page - 1) * self.STORAGE_PAGE_LENGTH
        self.storage_group.read()

    def persons(self):
        person = models.Person(0, self.handler)
        for i in range(len(datasets.PERSONS)):
            person.addr = i * models.Person.SIZE
            yield person

    def chariots(self):
        chariot = models.chariot(0, self.handler)
        for i in range(len(datasets.CHARIOTS)):
            chariot.addr = i * models.chariot.SIZE
            yield chariot

    def move_left(self):
        self._global.posx -= 1

    def move_right(self):
        self._global.posx += 1

    def move_up(self):
        self._global.posy -= 1

    def move_down(self):
        self._global.posy += 1

    def pull_through(self):
        for person in self.persons():
            person.hp = person.hpmax