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()
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
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()
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()
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
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