def palette_fade(self, update_scene, *args): new_palette = self.get_palette(*args) if new_palette is None: return palette = self.screen.get_palette() for i in range(32): if update_scene: ticks = pg.time.get_ticks() + FRAME_TIME else: ticks = (FRAME_TIME // 4) t = [ pg.Color( (palette[j].r * (31 - i) + new_palette[j].r * i) // 31, (palette[j].g * (31 - i) + new_palette[j].g * i) // 31, (palette[j].b * (31 - i) + new_palette[j].b * i) // 31, ) for j in range(256) ] self.set_screen_palette(t) if update_scene: self.clear_key_state() self.input_state.curdir = Direction.Unknown self.input_state.prevdir = Direction.Unknown self.update(False) self.make_scene() self.update_screen() self.process_event() while pg.time.get_ticks() < ticks: self.process_event() pg.time.delay(5)
def remove_equipment_effect(self, player_role, equip_part): p = self.equipment_effect[equip_part] for i in range(0, PlayerRoles.struct_size, Players.struct_size): pack_into('H', p._buffer, i + player_role * 2, 0) p.__init__(p._buffer) if equip_part == BodyPart.Hand: self.player_status[player_role][Status.DualAttack] = 0 elif equip_part == BodyPart.Wear: for i in range(self.max_party_member_index + 1): if self.party[i].player_role == player_role: player_role = i break else: return j = 0 for i in range(MAX_POISONS): w = self.poison_status[i][player_role].poison_id if w == 0: break if self.objects[w].poison.poison_level < 99: self.poison_status[j][player_role] = self.poison_status[i][player_role] j += 1 while j < MAX_POISONS: self.poison_status[j][player_role].poison_id = 0 self.poison_status[j][player_role].poison_script = 0 j += 1
def apply_wave(self, surface): save = self.apply_wave.__dict__ wave = [0] * 32 self.screen_wave += self.wave_progression self.screen_wave &= 0xFFFF if self.screen_wave == 0 or self.screen_wave >= 256: self.screen_wave = self.wave_progression = 0 return a = 0 b = 60 + 8 for i in range(16): b -= 8 a += b wave[i] = a * self.screen_wave // 256 wave[i + 16] = 320 - wave[i] a = save['index'] pxarray = pg.PixelArray(surface) for p in range(200): b = wave[a] if b > 0: pxarray[:320 - b, p], pxarray[320 - b:320, p] = pxarray[b:320, p], pxarray[:b, p] a = (a + 1) % 32 save['index'] = (save['index'] + 1) % 32 del pxarray surface.unlock()
def calc_cover_tiles(self, sprite): sx = pal_x(self.viewport) + pal_x(sprite.pos) sy = pal_y(self.viewport) + pal_y(sprite.pos) sh = bool(sx % 32) width, height = sprite.frame.size dx = dy = dh = 0 for y in range((sy - height - 15) // 16, sy // 16 + 1): for x in range((sx - width // 2) // 32, (sx + width // 2) // 32 + 1): for i in range(0 if x == (sx - width // 2) // 32 else 3, 5): if i == 0: dx, dy, dh = x, y, sh elif i == 1: dx = x - 1 elif i == 2: dx = x if sh else x - 1 dy = y + 1 if sh else y dh = 1 - sh elif i == 3: dx, dy, dh = x + 1, y, sh elif i == 4: dx = x + 1 if sh else x dy = y + 1 if sh else y dh = 1 - sh for l in range(2): tile = self.maps.get_tile_bitmap(dx, dy, dh, l) tile_hight = self.maps.get_tile_height(dx, dy, dh, l) if tile is not None and tile_hight > 0 and ( (dy + tile_hight) * 16 + dh * 8 >= sy): self.add_sprite_to_draw( tile, (dx * 32 + dh * 16 - 16 - pal_x(self.viewport), dy * 16 + dh * 8 + 7 + l + (tile_hight * 8) - pal_y(self.viewport)), tile_hight * 8 + l)
def scene_fade(self, step, *args): palette = self.get_palette(*args) if palette is None: return if step == 0: step = 1 self.need_to_fadein = False if step > 0: steps = range(0, 64, step) else: steps = range(63, -1, step) for i in steps: ticks = pg.time.get_ticks() + 100 self.clear_key_state() self.input_state.curdir = Direction.Unknown self.input_state.prevdir = Direction.Unknown self.update(False) self.make_scene() self.update_screen() new_palette = [ pg.Color((color.r * i) >> 6, (color.g * i) >> 6, (color.b * i) >> 6) for color in palette ] self.set_screen_palette(new_palette) self.process_event() while pg.time.get_ticks() <= ticks: self.process_event() pg.time.delay(5)
def fade_to_red(self): palette = self.get_palette() new_palette = copy.deepcopy(palette) pxarray = pg.PixelArray(self.screen) for x in range(self.screen.get_width()): for y in range(self.screen.get_height()): if pxarray[x, y] == 0x4F: pxarray[x, y] = 0x4E del pxarray self.screen.unlock() self.update_screen() for _ in range(32): for j in range(256): if j == 0x4F: continue color = (palette[j].r + palette[j].g + palette[j].b) // 4 + 64 if new_palette[j].r > color: new_palette[j].r -= min(new_palette[j].r - color, 8) elif new_palette[j].r < color: new_palette[j].r += min(color - new_palette[j].r, 8) if new_palette[j].g > 0: new_palette[j].g -= min(new_palette[j].g, 8) if new_palette[j].b > 0: new_palette[j].b -= min(new_palette[j].b, 8) self.set_screen_palette(new_palette) self.delay(75)
def scene_draw_sprites(self): self.sprite_to_draw.empty() for i in range(self.max_party_member_index + self.follower_num + 1): if i > MAX_PLAYERS_IN_PARTY: break sprite = self.player_sprites[i] if sprite is None: continue sprite_frame = sprite[self.party[i].frame] if sprite_frame is None: continue self.add_sprite_to_draw(sprite_frame, (self.party[i].x - sprite_frame.width // 2, self.party[i].y + self.layer + 10), self.layer + 6) self.calc_cover_tiles(self.sprite_to_draw.sprites()[-1]) for i in range( self.scenes[self.num_scene - 1].event_object_index, self.scenes[self.num_scene].event_object_index, ): evt_obj = self.event_objects[i] if evt_obj.state == ObjectState.Hidden: continue elif evt_obj.vanish_time > 0: continue elif evt_obj.state < 0: continue sprite = self.get_event_object_sprite((i & 0xFFFF) + 1) if sprite is None: continue frame = evt_obj.current_frame_num if evt_obj.sprite_frames_num == 3: if frame == 2: frame = 0 elif frame == 3: frame = 2 sprite_frame = sprite[evt_obj.direction * evt_obj.sprite_frames_num + frame] if sprite_frame is None: continue x = evt_obj.x - pal_x(self.viewport) x -= sprite_frame.width // 2 if x >= 320 or x < -sprite_frame.width: continue y = evt_obj.y - pal_y(self.viewport) y += evt_obj.layer * 8 + 9 vy = y - sprite_frame.height - evt_obj.layer * 8 + 2 if vy >= 200 or vy < -sprite_frame.height: continue self.add_sprite_to_draw(sprite_frame, (x, y), evt_obj.layer * 8 + 2) self.calc_cover_tiles(self.sprite_to_draw.sprites()[-1]) self.sprite_to_draw._spritelist.sort( key=lambda sprite: pal_y(sprite.pos)) for p in self.sprite_to_draw: x = pal_x(p.pos) y = pal_y(p.pos) - p.frame.height - p.layer p.frame.blit_to(self.screen, (x, y))
def update_equipments(self): self.equipment_effect = EquipmentEffect(None) for i in range(MAX_PLAYER_ROLES): for j in range(MAX_PLAYER_EQUIPMENTS): w = self.player_roles.equipment[j][i] if w != 0: self.objects[w].item.script_on_equip = self.run_trigger_script( self.objects[w].item.script_on_equip, i )
def yj2_build_tree(tree): tree.node = [YJ2_TreeNode(i) for i in range(641)] tree._list = [Pointer(tree.node, i) for i in range(321)] tree.node[0x280].parent = Pointer(tree.node, 0x280) for i, ptr in zip(range(0, 0x280, 2), range(0x141, 0x281)): tree.node[ptr].left = Pointer(tree.node, i) tree.node[ptr].right = Pointer(tree.node, i + 1) tree.node[i].parent = tree.node[i + 1].parent = Pointer(tree.node, ptr) tree.node[ptr].weight = tree.node[i].weight + tree.node[i + 1].weight return True
def compress_inventory(self): j = 0 for i in range(MAX_INVENTORY): # if self.inventory[i].item == 0: # break if self.inventory[i].amount > 0: self.inventory[j] = self.inventory[i] j += 1 for j in range(j, MAX_INVENTORY): self.inventory[j].amount = 0 self.inventory[j].amount_in_use = 0 self.inventory[j].item = 0
def load(self, index, gop): if self.index != index: data = self.read(index) if len(data): self.tiles = tuple( tuple( tuple( unpack_from('I', data, (y << 9) + (x << 3) + (h << 2))[0] for h in range(2)) for x in range(64)) for y in range(128)) self.sub_place = gop[index] self.index = index
def render(self, index, surface): width, height = 320, 200 pxarray = pg.PixelArray(surface) try: data = self.read(index) for y in range(height): for x in range(width): pxarray[x, y] = data[x + y * width] except AssertionError: pass del pxarray surface.unlock()
class RixInfo(object): # global various and flags adflag = ([0]*3+[1]*3) * 3 reg_data = tuple(x for x in range(22) if 1 - x % 8 // 6) ad_C0_offs = tuple(i % 3 + (i // 6) * 3 for i in range(18)) modify = array('I', ( 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 13, 16, 14, 17, 12, 15, 16, 0, 14, 0, 17, 0, 13, 0 )) bd_reg_data = array('B', ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x01, 0x01, 0x03, 0x0F, 0x05, 0x00, 0x01, 0x03, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0F, 0x07, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x04, 0x00, 0x08, 0x0C, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x04, 0x00, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0C, 0x00, 0x0F, 0x0B, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0F, 0x0B, 0x00, 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x0B, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x0B, 0x00, 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) ) pause_flag = 0 def __init__(me): me.buf_addr = [] me.buffer = [0] * 300 me.mus_block = 0 me.ins_block = 0 me.for40reg = [0x7F] * 18 me.a0b0_data2 = [0] * 11 me.a0b0_data3 = [0] * 18 me.a0b0_data4 = [0] * 18 me.a0b0_data5 = [0] * 96 me.addrs_head = [0] * 96 me.rix_stereo = 0 me.reg_bufs = [ADDT() for _ in range(18)] me.mus_time = 0x4268 me.play_end = 0 me.music_on = 0 me.insbuf = [0] * 28 me.band = 0 me.band_low = 0 me.e0_reg_flag = 0 me.bd_modify = 0 me.displace = [0] * 11 me.sustain = 0
def yj2_decompress(source, dst, dst_size): ptr = 0 tree = YJ2_Tree() src = source[4:] dest = 0 if not source or not yj2_build_tree(tree): return -1 length, = unpack_from('I', source) if length > dst_size: return -1 while True: node = Pointer(tree.node, 0x280) while node[0].value > 0x140: if yj2_bt(src, ptr): node = node[0].right else: node = node[0].left ptr += 1 val = node[0].value if tree.node[0x280].weight == 0x8000: for i in range(0x141): if tree._list[i][0].weight & 0x1: yj2_adjust_tree(tree, i) for node in tree.node: node.weight >>= 1 yj2_adjust_tree(tree, val) if val > 0xff: temp = 0 for i in range(8): temp |= yj2_bt(src, ptr) << i ptr += 1 tmp = temp & 0xff for i in range(8, yj2_data2[tmp & 0xf] + 6): temp |= yj2_bt(src, ptr) << i ptr += 1 temp >>= yj2_data2[tmp & 0xf] pos = (temp & 0x3f) | (yj2_data1[tmp] << 6) if pos == 0xfff: break pre = dest - pos - 1 for _ in range(val - 0xfd): dst[dest] = dst[pre] dest += 1 pre += 1 else: dst[dest] = val dest += 1 return length
def search(self): x = pal_x(self.viewport) + pal_x(self.partyoffset) y = pal_y(self.viewport) + pal_y(self.partyoffset) x_offset = 16 if self.party_direction in { Direction.North, Direction.East } else -16 y_offset = 8 if self.party_direction in { Direction.South, Direction.East } else -8 pos = [(x, y)] for i in range(4): pos.extend([ (x + x_offset, y + y_offset), (x, y + y_offset * 2), (x + x_offset, y), ]) x += x_offset y += y_offset for i in range(13): dh = bool(pal_x(pos[i]) % 32) dx = pal_x(pos[i]) // 32 dy = pal_y(pos[i]) // 16 for k in range(self.scenes[self.num_scene - 1].event_object_index, self.scenes[self.num_scene].event_object_index): p = self.event_objects[k] ex = p.x // 32 ey = p.y // 16 eh = bool(p.x % 32) if p.state <= 0: continue elif p.trigger_mode >= TriggerMode.TouchNear: continue elif p.trigger_mode * 6 - 4 < i: continue elif not (dx == ex and dy == ey and dh == eh): continue if p.sprite_frames_num * 4 > p.current_frame_num: p.current_frame_num = 0 p.direction = (self.party_direction + 2) % 4 for l in range(self.max_party_member_index + 1): self.party[l].frame = self.party_direction * 3 self.make_scene() self.update_screen() p.trigger_script = self.run_trigger_script( p.trigger_script, k + 1) self.delay(50) self.clear_key_state() return
def draw_number(self, num, length, pos, color, align): if color == NumColor.Blue: f = 29 elif color == NumColor.Cyan: f = 56 else: f = 19 i = num actual_length = 0 while i > 0: i //= 10 actual_length += 1 actual_length = min(length, actual_length) or 1 x, y = pos x -= 6 if align == NumAlign.Left: x += 6 * actual_length elif align == NumAlign.Mid: x += 3 * (length + actual_length) elif align == NumAlign.Right: x += 6 * length for _ in range(actual_length): self.sprite_ui[f + num % 10].blit_to(self.screen, (x, y)) x -= 6 num //= 10
def rixdup(rix_data): """ taken from palresearch rix utils """ if len(rix_data) < 0xC: return rix_data rhythm_offset, = struct.unpack_from("<I", rix_data, 0xC) new_data = rix_data[:rhythm_offset] for _ in range(2): # dup whole rhythms 2 times! new_data += rix_data[rhythm_offset: -2] for _ in range(11): # mute all channels new_data += struct.pack("<BB", 0, 0xC0 + _) for _ in range(1): # delay time new_data += struct.pack("<BB", 0, 1) new_data += rix_data[-2:] return new_data
def check_obstacle(self, pos, check_event_objects, self_object): x, y = pos if not pg.Rect(0, 0, 2047, 2047).collidepoint(x, y): return True x, xr = divmod(x, 32) y, yr = divmod(y, 16) h = 0 if xr + yr * 2 >= 16: if xr + yr * 2 >= 48: x += 1 y += 1 elif 32 - xr + yr * 2 < 16: x += 1 elif 32 - xr + yr * 2 < 48: h = 1 else: y += 1 if self.maps.tile_blocked(x, y, h): return True if check_event_objects: for i in range( self.scenes[self.num_scene - 1].event_object_index, self.scenes[self.num_scene].event_object_index, ): p = self.event_objects[i] if i == self_object - 1: continue if p.state >= ObjectState.Blocker: if abs(p.x - pal_x(pos)) + abs(p.y - pal_y(pos)) * 2 < 16: return True return False
def ending_animation(self): y_pos_girl = 180 upper = self.create_compatible_surface(self.screen) self.fbp.render(69 if is_win95 else 61, upper) lower = self.create_compatible_surface(self.screen) self.fbp.render(70 if is_win95 else 62, lower) buf = self.mgo[571] buf_girl = self.mgo[572] src_rect = pg.Rect(0, 0, 320, 0) dst_rect = pg.Rect(0, 0, 320, 0) self.screen_wave = 2 for i in range(400): src_rect.h = dst_rect.h = 200 - i // 2 src_rect.y, dst_rect.y = 0, i // 2 self.blit(lower, dst_rect, src_rect) src_rect.h = dst_rect.h = i // 2 src_rect.y, dst_rect.y = 200 - i // 2, 0 self.blit(upper, dst_rect, src_rect) self.apply_wave(self.screen) buf[0].blit_to(self.screen, (0, -400 + i)) buf[1].blit_to(self.screen, (0, -200 + i)) y_pos_girl -= i & 1 if y_pos_girl < 80: y_pos_girl = 80 buf_girl[(pg.time.get_ticks() // 50) % 4].blit_to( self.screen, (220, y_pos_girl)) self.update_screen() if self.need_fadein: self.fadein(1) self.need_fadein = False upper.set_palette(self.screen.get_palette()) lower.set_palette(self.screen.get_palette()) self.delay(50) self.screen_wave = 0
def player_level_up(self, player_role, num_level): def stat_limit(group, player_role): if group[player_role] > 999: group[player_role] = 999 self.player_roles.level[player_role] += num_level if self.player_roles.level[player_role] > MAX_LEVELS: self.player_roles.level[player_role] = MAX_LEVELS for i in range(num_level): self.player_roles.max_hp[player_role] += 10 + randint(0, 8) self.player_roles.max_mp[player_role] += 8 + randint(0, 6) self.player_roles.attack_strength[player_role] += 4 + randint(0, 1) self.player_roles.magic_strength[player_role] += 2 + randint(0, 1) self.player_roles.defense[player_role] += 2 + randint(0, 1) self.player_roles.dexterity[player_role] += 2 + randint(0, 1) self.player_roles.flee_rate[player_role] += 2 attrs = [ 'max_hp', 'max_mp', 'attack_strength', 'magic_strength', 'defense', 'dexterity', 'flee_rate', ] for attr in attrs: stat_limit(getattr(self.player_roles, attr), player_role) self.exp.primary_exp[player_role].exp = 0 self.exp.primary_exp[player_role].level = self.player_roles.level[player_role]
def get_item_amount(self, item): for i in range(MAX_INVENTORY): if self.inventory[i].item == 0: break if self.inventory[i].item == item: return self.inventory[i].amount return 0
def __init__(self, path=None, data=None, yj1=True): # path和data不能同时是None assert path or data self.yj1 = YJ1Decoder() if yj1 else None try: # 优先使用path(优先从文件读取) if path: with open(path, 'rb') as f: self._content = memoryview(f.read()) else: self._content = memoryview(data) # 偏移(索引)表长度,假设文件前4位为6C 02 00 00(little-end的int值为 # 26CH = 620),说明索引表长度为620字节,即620/4 = 155个整数,由于第一个 # 整数被用于存储表长度,因此实际上只有后面154个整数存的是偏移量。另一方面, # 最后一个整数指向文件末尾,也就是文件的长度,因此实际上MKF内部的文件是由 # 前后两个偏移量之间的byte表示的。这样由于一共有154个个偏移量,因此共有 # 153个文件 # # !!!补充:第一个int(前四位)不仅是偏移表长度,也是第一个文件的开头 # ABC.MKF中前面两个4位分别相等只是巧合(第一个文件为0) self.count = unpack_from('<I', self._content, 0)[0] // 4 # - 1 self.indexes = tuple( unpack_from('<I', self._content, i << 2)[0] for i in range(self.count)) self.cache = [None] * self.count # 减去最后一个偏移量,对外而言,count就表示mkf文件中的子文件个数 self.count -= 1 except IOError: raise IOError('error occurs when try to open file ' + path) except TypeError: raise TypeError('data can not be converted to memoryview')
def player_can_attack_all(self, player_role): f = False for i in range(MAX_PLAYER_EQUIPMENTS + 1): if self.equipment_effect[i].attack_all[player_role] != 0: f = True break return f
def show_fbp(self, chunk_num, fade): index = [0, 3, 1, 5, 2, 4] if self.cur_effect_sprite != 0: buf_sprite = self.mgo[self.cur_effect_sprite] buf = partial(self.fbp.render, chunk_num) if fade: p = self.create_compatible_surface(self.screen) fade = (fade + 1) * 10 buf(p) self.screen_bak.blit(self.screen, (0, 0)) for i in range(16): for j in range(6): self.screen_bak.lock() y = 0 x = index[j] buf_screen = pg.PixelArray(p) buf_bak = pg.PixelArray(self.screen_bak) while y < 200: a = buf_screen[x, y] b = buf_bak[x, y] if i > 0: if (a & 0x0F) > (b & 0x0F): b += 1 elif (a & 0x0F) < (b & 0x0F): b -= 1 buf_bak[x, y] = (a & 0xF0) | (b & 0x0F) x += 6 if x >= 320: x -= 320 y += 1 del buf_bak del buf_screen self.screen_bak.unlock() self.blit(self.screen_bak, (0, 0)) if self.cur_effect_sprite != 0: f = pg.time.get_ticks() // 150 buf_sprite[f % len(buf_sprite)].blit_to( self.screen, (0, 0)) self.update_screen() self.delay(fade) del p if chunk_num != (68 if is_win95 else 49): buf(self.screen) self.update_screen()
def color_fade(self, delay, color, from_color): palette = self.get_palette() delay = (delay or 1) * 10 if from_color: new_palette = [pg.Color(*palette[color])] * 256 for i in range(64): for j in range(256): if new_palette[j].r > palette[j].r: new_palette[j].r -= 4 elif new_palette[j].r < palette[j].r: new_palette[j].r += 4 if new_palette[j].g > palette[j].g: new_palette[j].g -= 4 elif new_palette[j].g < palette[j].g: new_palette[j].g += 4 if new_palette[j].b > palette[j].b: new_palette[j].b -= 4 elif new_palette[j].b < palette[j].b: new_palette[j].b += 4 self.set_screen_palette(new_palette) self.delay(delay) self.set_screen_palette(palette) else: new_palette = copy.deepcopy(palette) for i in range(64): for j in range(256): if new_palette[j].r > palette[color].r: new_palette[j].r -= 4 elif new_palette[j].r < palette[color].r: new_palette[j].r += 4 if new_palette[j].g > palette[color].g: new_palette[j].g -= 4 elif new_palette[j].g < palette[color].g: new_palette[j].g += 4 if new_palette[j].b > palette[color].b: new_palette[j].b -= 4 elif new_palette[j].b < palette[color].b: new_palette[j].b += 4 self.set_screen_palette(new_palette) self.delay(delay) new_palette = [pg.Color(*palette[color])] * 256 self.set_screen_palette(new_palette)
def __mul__(self, other): if isinstance(other, int): return StructureMeta(self.format + '_' + str(other), (Structure, ), { '_fields_': [ (self.format, i) for i in range(other) ] }) else: raise NotImplementedError('unsupported operand type(s) for *: %s and %s' % ( repr(type(self).__name__), repr(type(other).__name__)))
def __init__(self): self.shake_time = 0 self.shake_level = 0 self.num_palette = 0 self.night_palette = False self.need_fadein = False offset = 0x28 max_index = 11 file_size = 0x300 try: with open('pat.mkf', 'rb') as f: content = bytearray(f.read()) # 新建一个数组保存11个调色板文件(每个调色板256种颜色) self.palettes = [[ pg.Color(*(x << 2 for x in content[pos:pos + 3])) for pos in range(index, index + file_size, 3) ] for index in range(offset, offset + max_index * file_size, file_size)] except IOError: print('error occurs when try to open file pat.mkf')
def is_player_poisoned_by_kind(self, player_role, poison_id): index = 0 while index < self.max_party_member_index + 1: if self.party[index].player_role == player_role: break index += 1 if index > self.max_party_member_index: return False for i in range(MAX_POISONS): if self.poison_status[i][index].poison_id == poison_id: return True return False
def cure_poison_by_kind(self, player_role, poison_id): index = 0 while index < self.max_party_member_index + 1: if self.party[index].player_role == player_role: break index += 1 if index > self.max_party_member_index: return for i in range(MAX_POISONS): if self.poison_status[i][index].poison_id == poison_id: self.poison_status[i][index].poison_id = 0 self.poison_status[i][index].poison_script = 0
def add_magic(self, player_role, magic): for i in range(MAX_PLAYER_MAGICS): if self.player_roles.magic[i][player_role] == magic: return False i = 0 while i < MAX_PLAYER_MAGICS: if self.player_roles.magic[i][player_role] == 0: break i += 1 if i >= MAX_PLAYER_MAGICS: return False self.player_roles.magic[i][player_role] = magic return True