コード例 #1
0
 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)
コード例 #2
0
 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))
コード例 #3
0
 def start_dialog_with_offset(self, dialog_location, font_color,
                              num_char_face, playing_rng, x_off, y_off):
     if self.in_battle and self.updated_in_battle:
         self.update_screen()
         self.updated_in_battle = True
     self.icon = 0
     self.pos_icon = 0
     self.current_dialog_line_num = 0
     self.pos_dialog_title = 12, 8
     self.user_skip = False
     if font_color != 0:
         self.current_font_color = font_color
     if playing_rng and num_char_face:
         self.screen_bak.blit(self.screen, (0, 0))
         self.playing_rng = True
     if dialog_location == DialogPos.Upper:
         if num_char_face > 0:
             w, h = self.rgm[num_char_face].size
             pos = (max(48 - w // 2 + x_off,
                        0), max(55 - h // 2 + y_off, 0))
             self.rgm[num_char_face].blit_to(self.screen, pos)
             rect = pg.Rect(pos, (w, h))
             self.update_screen(rect)
             self.pos_dialog_title = 80, 8
             self.pos_dialog_text = 96, 26
         else:
             self.pos_dialog_title = 12, 8
             self.pos_dialog_text = 44, 26
     elif dialog_location == DialogPos.Center:
         self.pos_dialog_text = 80, 40
     elif dialog_location == DialogPos.Lower:
         if num_char_face > 0:
             pos = (
                 270 - self.rgm[num_char_face].width // 2 + x_off,
                 144 - self.rgm[num_char_face].height // 2 + y_off,
             )
             self.rgm[num_char_face].blit_to(self.screen, pos)
             self.update_screen()
             self.pos_dialog_title = 4, 108
             self.pos_dialog_text = 20, 126
         else:
             self.pos_dialog_title = 12, 108
             self.pos_dialog_text = 44, 126
     elif dialog_location == DialogPos.CenterWindow:
         self.pos_dialog_text = 160, 40
     self.pos_dialog_title = (pal_x(self.pos_dialog_title) + x_off,
                              pal_y(self.pos_dialog_title) + y_off)
     self.pos_dialog_text = (pal_x(self.pos_dialog_text) + x_off,
                             pal_y(self.pos_dialog_text) + y_off)
     self.dialog_position = dialog_location
コード例 #4
0
 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
コード例 #5
0
 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
コード例 #6
0
 def show_dialog_text(self, text):
     self.clear_key_state()
     self.icon = 0
     if self.in_battle and not self.updated_in_battle:
         self.update_screen()
         self.updated_in_battle = False
     if self.current_dialog_line_num > 3:
         self.dialog_wait_for_key()
         self.current_dialog_line_num = 0
         self.blit(self.screen_bak, (0, 0))
         self.update_screen()
     x = pal_x(self.pos_dialog_text)
     y = pal_y(self.pos_dialog_text) + self.current_dialog_line_num * 18
     if self.dialog_position == DialogPos.CenterWindow:
         length = wcwidth.wcswidth(text)
         pos = (pal_x(self.pos_dialog_text) - length * 4,
                pal_y(self.pos_dialog_text))
         box = self.one_line_box_with_shadow(pos, (length + 1) // 2, False,
                                             self.dialog_shadow)
         rect = pg.Rect(pos, (320 - pal_x(pos) * 2 + 32, 64))
         self.update_screen(rect)
         self.display_text(text,
                           pal_x(pos) + 8 + ((length & 1) << 2),
                           pal_y(pos) + 10, True)
         self.update_screen(rect)
         self.dialog_wait_for_key_with_maximum_seconds(1.4)
         self.delete_box(box)
         self.update_screen(rect)
         self.end_dialog()
     else:
         if (self.current_dialog_line_num == 0
                 and self.dialog_position != DialogPos.Center
                 and text[-1] in {u'\uff1a', u'\u2236', u':'}):
             self.draw_text(text, self.pos_dialog_title,
                            FONT_COLOR_CYAN_ALT, True, True)
         else:
             if not self.playing_rng and self.current_dialog_line_num == 0:
                 self.screen_bak.blit(self.screen, (0, 0))
             x = self.display_text(text, x, y, False)
             if self.user_skip:
                 self.update_screen()
             self.pos_icon = x, y
             self.current_dialog_line_num += 1
コード例 #7
0
 def update_party(self):
     if self.input_state.curdir != Direction.Unknown:
         x_offset = -16 if self.input_state.curdir in {
             Direction.West, Direction.South
         } else 16
         y_offset = -8 if self.input_state.curdir in {
             Direction.West, Direction.North
         } else 8
         x_source = pal_x(self.viewport) + pal_x(self.partyoffset)
         y_source = pal_y(self.viewport) + pal_y(self.partyoffset)
         x_target = x_source + x_offset
         y_target = y_source + y_offset
         self.party_direction = self.input_state.curdir
         if not self.check_obstacle((x_target, y_target), True, 0):
             for i in range(4, 0, -1):
                 self.trail[i] = self.trail[i - 1]
             self.trail[0].direction = self.input_state.curdir
             self.trail[0].x = x_source
             self.trail[0].y = y_source
             self.viewport = (pal_x(self.viewport) + x_offset,
                              pal_y(self.viewport) + y_offset)
             self.update_party_gestures(True)
             return
     self.update_party_gestures(False)
コード例 #8
0
    def blit_mono_color(self, dst_surface, pos, color_shift, color=None):
        pxarray = pg.PixelArray(dst_surface)
        max_w, max_h = dst_surface.get_size()
        ui_width, ui_height = self.size
        offset = 4

        i = 0
        if color is not None:
            color &= 0xF0
        while i < ui_width * ui_height:
            num = self.data[offset]
            offset += 1
            if (num & 0x80) and num <= 0x80 + ui_width:
                i += num - 0x80
            else:
                j = -1
                while j < num - 1:
                    j += 1
                    y = (i + j) // ui_width + pal_y(pos)
                    x = (i + j) % ui_width + pal_x(pos)
                    if x < 0:
                        j += -x - 1
                        continue
                    elif x >= max_w:
                        j += x - max_w
                        continue
                    if y < 0:
                        j += -y * ui_width - 1
                        continue
                    elif y >= max_h:
                        return
                    b = self.data[offset + j] & 0x0F
                    if b + color_shift > 0x0F:
                        b = 0x0F
                    elif b + color_shift < 0:
                        b = 0
                    else:
                        b += color_shift
                    if color is None:
                        pxarray[x, y] = b | (self.data[offset + j] & 0xF0)
                    else:
                        pxarray[x, y] = b | color
                offset += num
                i += num
コード例 #9
0
 def update(self, trigger):
     if trigger:
         if self.entering_scene:
             self.entering_scene = False
             i = self.num_scene - 1
             self.scenes[i].script_on_enter = self.run_trigger_script(
                 self.scenes[i].script_on_enter, 0xFFFF)
             if self.entering_scene or self.to_start:
                 return
             self.clear_key_state()
             self.make_scene()
         for event_object_id in range(len(self.event_objects)):
             p = self.event_objects[event_object_id]
             if p.vanish_time != 0:
                 p.vanish_time += 1 if p.vanish_time < 0 else -1
         for event_object_id in range(
                 self.scenes[self.num_scene - 1].event_object_index + 1,
                 self.scenes[self.num_scene].event_object_index + 1,
         ):
             p = self.event_objects[event_object_id - 1]
             if p.vanish_time != 0:
                 continue
             if p.state < 0:
                 if (p.x < pal_x(self.viewport)
                         or p.x > pal_x(self.viewport) + 320
                         or p.y < pal_y(self.viewport)
                         or p.y > pal_y(self.viewport) + 320):
                     p.state = abs(p.state)
                     p.current_frame_num = 0
             elif p.state > 0 and p.trigger_mode >= TriggerMode.TouchNear:
                 if (abs(
                         pal_x(self.viewport) + pal_x(self.partyoffset) -
                         p.x) + abs(
                             pal_y(self.viewport) +
                             pal_y(self.partyoffset) - p.y) * 2 <
                     (p.trigger_mode - TriggerMode.TouchNear) * 32 + 16):
                     if p.sprite_frames_num:
                         p.current_frame_num = 0
                         x_offset = pal_x(self.viewport) + \
                                    pal_x(self.partyoffset) - p.x
                         y_offset = pal_y(self.viewport) + \
                                    pal_y(self.partyoffset) - p.y
                         if x_offset > 0:
                             p.direction = Direction.East if y_offset > 0 else Direction.North
                         else:
                             p.direction = Direction.South if y_offset > 0 else Direction.West
                         self.update_party_gestures(False)
                         self.make_scene()
                         self.update_screen()
                     p.trigger_script = self.run_trigger_script(
                         p.trigger_script, event_object_id)
                     self.clear_key_state()
                     if self.entering_scene or self.to_start:
                         return
     for event_object_id in range(
             self.scenes[self.num_scene - 1].event_object_index + 1,
             self.scenes[self.num_scene].event_object_index + 1,
     ):
         p = self.event_objects[event_object_id - 1]
         if p.state > 0 and p.vanish_time == 0:
             script_entry = p.auto_script
             if script_entry != 0:
                 p.auto_script = self.run_auto_script(
                     script_entry, event_object_id)
                 if self.entering_scene or self.to_start:
                     return
         if (trigger and p.state >= ObjectState.Blocker
                 and p.sprite_num != 0 and
                 abs(p.x - pal_x(self.viewport) - pal_x(self.partyoffset)) +
                 abs(p.y - pal_y(self.viewport) - pal_y(self.partyoffset)) *
                 2 <= 12):
             direction = (p.direction + 1) % 4
             for i in range(4):
                 x = pal_x(self.viewport) + pal_x(self.partyoffset)
                 y = pal_y(self.viewport) + pal_y(self.partyoffset)
                 x += -16 if direction in {Direction.West, Direction.South
                                           } else 16
                 y += -8 if direction in {Direction.West, Direction.North
                                          } else 8
                 pos = x, y
                 if not self.check_obstacle(pos, True, 0):
                     self.viewport = (x - pal_x(self.partyoffset),
                                      y - pal_y(self.partyoffset))
                     break
                 direction = (direction + 1) % 4
     self.frame_num += 1
コード例 #10
0
 def update_party_gestures(self, walking):
     save = self.update_party_gestures.__dict__
     step_frame_follower = step_frame_leader = 0
     if walking:
         save['this_step_frame'] = (save['this_step_frame'] + 1) % 4
         if save['this_step_frame'] & 1:
             step_frame_leader = (save['this_step_frame'] + 1) // 2
             step_frame_follower = 3 - step_frame_leader
         else:
             step_frame_leader = step_frame_follower = 0
         self.party[0].x = pal_x(self.partyoffset)
         self.party[0].y = pal_y(self.partyoffset)
         if self.player_roles.walk_frames[self.party[0].player_role] == 4:
             self.party[0].frame = self.party_direction * 4 + save[
                 'this_step_frame']
         else:
             self.party[
                 0].frame = self.party_direction * 3 + step_frame_leader
         for i in range(1, self.max_party_member_index + 1):
             self.party[i].x = self.trail[1].x - pal_x(self.viewport)
             self.party[i].y = self.trail[1].y - pal_y(self.viewport)
             if i == 2:
                 self.party[i].x += -16 if self.trail[1].direction in {
                     Direction.East, Direction.West
                 } else 16
                 self.party[i].y += 8
             else:
                 self.party[i].x += 16 if self.trail[1].direction in {
                     Direction.West, Direction.South
                 } else -16
                 self.party[i].y += 8 if self.trail[1].direction in {
                     Direction.West, Direction.North
                 } else -8
             if self.check_obstacle(
                 (self.party[i].x + pal_x(self.viewport),
                  self.party[i].y + pal_y(self.viewport)), True, 0):
                 self.party[i].x = self.trail[1].x - pal_x(self.viewport)
                 self.party[i].y = self.trail[1].y - pal_y(self.viewport)
             if self.player_roles.walk_frames[
                     self.party[i].player_role] == 4:
                 self.party[i].frame = self.trail[2].direction * \
                                       4 + save['this_step_frame']
             else:
                 self.party[i].frame = self.trail[2].direction * \
                                       3 + step_frame_leader
         if self.follower_num > 0:
             self.party[self.max_party_member_index +
                        1].x = self.trail[3].x - pal_x(self.viewport)
             self.party[self.max_party_member_index +
                        1].y = self.trail[3].y - pal_y(self.viewport)
             self.party[self.max_party_member_index +
                        1].frame = (self.trail[3].direction * 3 +
                                    step_frame_follower)
     else:
         i = self.player_roles.walk_frames[self.party[0].player_role] or 3
         self.party[0].frame = self.party_direction * i
         for i in range(self.max_party_member_index):
             f = self.player_roles.walk_frames[self.party[
                 i + 1].player_role] or 3
             self.party[i + 1].frame = self.trail[2].direction * f
         if self.follower_num > 0:
             self.party[self.max_party_member_index +
                        1].frame = self.trail[3].direction * 3
         save['this_step_frame'] &= 2
         save['this_step_frame'] ^= 2