#! /usr/bin/env python """ Copyright 2008 Ben Sarsgard This file is part of ZedZed. ZedZed is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ZedZed is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ZedZed. If not, see . """ import os, sys import pygame import random import cPickle as pickle from pygame.locals import * from helpers import * from Actors import * from Board import Board from EventLog import EventLog from Items import * if not pygame.font: print 'Error, fonts disabled' sys.exit() if not pygame.mixer: print 'Error, sound disabled' sys.exit() class ZedZedMain: """The Main PyZed Class - This class handles the main initialization and creating of the Game.""" def __init__(self, width=640, height=480): """Initialize""" """Initialize PyGame""" pygame.init() """Set the window Size""" self.SetSizes((width, height)) self.current_action = None self.mouse_pos = None self.mouse_targets = [] self.crosshair_pos = None self.action_push = 0 self.action_attack = 1 self.action_move = 2 self.action_door = 3 self.action_barricade = 4 self.action_range_attack = 5 def SetSizes(self, screen_size): self.width = max(screen_size[0], 640) self.height = max(screen_size[1], 400) self.view_width = self.width self.view_height = self.height if (self.height >= 500): self.board_scale = 1 self.text_spacing = 20 self.stat_font_size = 16 self.fps_font_size = 12 self.margin = 10 self.event_font_size = 12 self.event_spacing = 15 self.sidebar_width = 200 else: self.board_scale = 2 self.text_spacing = 12 self.stat_font_size = 10 self.fps_font_size = 8 self.margin = 6 self.event_font_size = 8 self.event_spacing = 10 self.sidebar_width = 120 self.sidebar_alpha = 30 self.log_alpha = 50 self.mini_map_alpha = 200 self.fog_alpha = 100 self.screen = pygame.display.set_mode((self.width, self.height), pygame.RESIZABLE) """Create the background""" #background_image = load_image('background_800x600.png') #background_rect = pygame.Rect(0, 0, self.width, self.height) self.background = pygame.Surface(self.screen.get_size()) self.background = self.background.convert() self.background.set_alpha(255) self.background.set_colorkey((0,0,0)) #self.background.blit(background_image, background_rect) self.stat_font = pygame.font.Font('freesansbold.ttf', self.stat_font_size) self.fps_font = pygame.font.Font('freesansbold.ttf', self.fps_font_size) self.event_font = pygame.font.Font('freesansbold.ttf', self.event_font_size) def LoadObjects(self): """Load the sprites that we need""" self.log = EventLog() self.log.Push("Hello, player!") self.current_items = [] if os.path.exists(os.path.join('data', 'saves', 'player.dat')): # load the last game self.Load() else: # make a new game self.board = Board('Rural') self.meta_board = [[self.board.board_id]] # add the player pos_x = 0 pos_y = 0 while self.board.CanMove(None, pos_x, pos_y) == False or self.board.IsInside(pos_x, pos_y) == False: pos_x = random.randint(0, self.board.width - 1) pos_y = random.randint(0, self.board.height - 1) self.player = Player(pos_x, pos_y, self.board.board_id) self.board.actors.append(self.player) def MainLoop(self): self.clock = pygame.time.Clock() self.LoadObjects() self.board.CalculateLineOfSight(self.player) pygame.display.flip() while 1: self.clock.tick() if self.player.action_debt > 0: self.ProcessTurn() else: for event in pygame.event.get(): if event.type == pygame.QUIT: self.Exit() elif event.type == KEYDOWN: action = None if ((event.key == K_RIGHT) or (event.key == K_LEFT) or (event.key == K_UP) or (event.key == K_DOWN)): if self.current_action is None: # default action is move/push if self.Move(event.key): self.ProcessTurn() else: target = self.player.GetTarget(event.key, self.board.actors) if target != None: if self.PushTarget(self.player, target): self.Move(event.key) self.ProcessTurn() elif self.current_action == self.action_move: if self.Move(event.key): self.ProcessTurn() elif self.current_action == self.action_push: target = self.player.GetTarget(event.key, self.board.actors) if target != None: if self.PushTarget(self.player, target): self.Move(event.key) self.ProcessTurn() elif self.current_action == self.action_attack: target = self.player.GetTarget(event.key, self.board.actors) if target != None: if self.AttackTarget(self.player, target): self.ProcessTurn() elif self.Unbarricade(event.key): self.ProcessTurn() elif self.current_action == self.action_door: if self.OpenOrCloseDoor(event.key): self.ProcessTurn() elif self.current_action == self.action_barricade: if self.Barricade(event.key): self.ProcessTurn() elif self.current_action == self.action_range_attack: self.MoveCrosshair(event.key) action = self.action_range_attack elif ((event.key == K_SPACE) or (event.key == K_RETURN)): if self.current_action == self.action_range_attack: if self.RangeAttack(self.player, self.crosshair_pos): self.ProcessTurn() else: self.player.Rest() self.ProcessTurn() elif (event.key == K_r): self.Rest() elif (event.key == K_0): self.GetItem(0) elif (event.key == K_1): self.GetItem(1) elif (event.key == K_2): self.GetItem(2) elif (event.key == K_3): self.GetItem(3) elif (event.key == K_4): self.GetItem(4) elif (event.key == K_5): self.GetItem(5) elif (event.key == K_6): self.GetItem(6) elif (event.key == K_7): self.GetItem(7) elif (event.key == K_8): self.GetItem(8) elif (event.key == K_9): self.GetItem(9) elif (event.key == K_i): self.ShowInventoryScreen() elif (event.key == K_a): if self.current_action == self.action_range_attack: if self.RangeAttack(self.player, self.crosshair_pos): self.ProcessTurn() else: if self.player.weapon is not None and self.player.weapon.reach > 1: action = self.action_range_attack self.crosshair_pos = (self.player.pos_x, self.player.pos_y) else: action = self.action_attack elif (event.key == K_m): action = self.action_move elif (event.key == K_p): action = self.action_push elif (event.key == K_d): action = self.action_door elif (event.key == K_b): action = self.action_barricade elif (event.key == K_k): self.player.wounds = 100 elif (event.key == K_h): self.log.Push("Q: Quit") self.log.Push("K: Kill yourself") self.log.Push("S: Save game") self.log.Push("I: Inventory screen") self.log.Push("R: Rest") self.log.Push("#: Pick up item number #") self.log.Push("B+Arrow: Barricade") self.log.Push("D+Arrow: Door open/close") self.log.Push("P/A/M+Arrow: Push/Attack/Move in direction") self.log.Push("Arrow: Move or Push in direction") self.log.Push("COMMAND REFERENCE:") elif (event.key == K_s): self.Save() elif (event.key == K_l): self.Load() elif (event.key == K_q): self.Exit() if action is None: self.current_action = None self.crosshair_pos = None else: self.current_action = action elif event.type == MOUSEMOTION: self.mouse_pos = event.pos elif event.type == MOUSEBUTTONDOWN: tile = self.board.GetTileAt(self.view_width, self.view_height, self.player, self.mouse_pos) if event.button == 3 and self.current_action is None: # default action is move/attack if self.MoveTo(tile[0], tile[1]): self.ProcessTurn() else: if self.RangeAttack(self.player, tile): self.ProcessTurn() else: #if self.current_action == self.action_move: # if self.Move(event.key): # self.ProcessTurn() #elif self.current_action == self.action_door: # if self.OpenOrCloseDoor(event.key): # self.ProcessTurn() #elif self.current_action == self.action_barricade: # if self.Barricade(event.key): # self.ProcessTurn() if self.current_action == self.action_push: target = self.GetTargetAt(tile) if target != None: if self.PushTarget(self.player, target): self.MoveTo(tile[0], tile[1]) self.ProcessTurn() elif self.current_action == self.action_attack: target = self.GetTargetAt(tile) if target != None: if self.AttackTarget(self.player, target): self.ProcessTurn() elif self.UnbarricadeAt(tile[0], tile[1]): self.ProcessTurn() elif self.current_action == self.action_range_attack: if self.RangeAttack(self.player, tile): self.ProcessTurn() self.current_action = None self.crosshair_pos = None elif event.type == pygame.VIDEORESIZE: self.SetSizes(event.dict['size']) mini_map = pygame.Surface((self.board.width, self.board.height)) board_tiles, fog_tiles, mini_map = self.board.Draw(self.view_width * self.board_scale, self.view_height * self.board_scale, mini_map, self.player, self.crosshair_pos) #board_tiles, fog_tiles = pygame.sprite.Group(), pygame.sprite.Group() # draw the board self.screen.fill((0,0,0)) if self.board_scale == 1: fog_surface = pygame.Surface((self.view_width, self.view_height)) fog_surface.set_alpha(self.fog_alpha) fog_surface.set_colorkey((0,0,0)) fog_rect = pygame.Rect(0, 0, self.view_width, self.view_height) fog_tiles.draw(fog_surface) board_tiles.draw(self.screen) self.screen.blit(fog_surface, fog_rect) #feature_sprites.draw(self.screen) #barricade_sprites.draw(self.screen) #item_sprites.draw(self.screen) #actor_sprites.draw(self.screen) #fog_tiles.draw(self.screen) #overlay_sprites.draw(self.screen) else: board_surface = pygame.Surface((self.view_width * self.board_scale, self.view_height * self.board_scale)) board_rect = pygame.Rect(0, 0, self.view_width, self.view_height) board_tiles.draw(board_surface) #feature_sprites.draw(board_surface) #barricade_sprites.draw(board_surface) #item_sprites.draw(board_surface) #actor_sprites.draw(board_surface) #fog_tiles.draw(board_surface) #overlay_sprites.draw(board_surface) board_surface = pygame.transform.scale(board_surface, (self.view_width, self.view_height)) self.screen.blit(board_surface, board_rect) # drow the background self.screen.blit(self.background, (0, 0)) # draw the mini map mini_map_x = self.width - self.margin - self.sidebar_width mini_map_width = self.sidebar_width mini_map_height = self.sidebar_width mini_map_y = self.height - self.margin - self.sidebar_width if mini_map_width != self.board.width or mini_map_height != self.board.height: mini_map = pygame.transform.scale(mini_map, (mini_map_width, mini_map_height)) mini_map_rect = pygame.Rect(mini_map_x, mini_map_y, mini_map_width, mini_map_height) #bg_surface = pygame.Surface((mini_map_width, mini_map_height)) #bg_surface.fill((0,0,0)) mini_map.set_alpha(self.mini_map_alpha) #self.screen.blit(bg_surface, mini_map_rect) self.screen.blit(mini_map, mini_map_rect) # draw text print_x = self.margin print_y = self.margin bg_surface = pygame.Surface((self.sidebar_width, self.height - mini_map_height - self.margin * 3)) bg_surface.fill((255,0,0)) bg_surface.set_alpha(self.sidebar_alpha) bg_rect = pygame.Rect(print_x, print_y, self.sidebar_width, self.height - mini_map_height - self.margin * 3) self.screen.blit(bg_surface, bg_rect) wounds_text, wounds_rect, shadow_text, shadow_rect = load_shadow_text("Wounds: %i" % self.player.wounds, self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin) self.screen.blit(shadow_text, shadow_rect) fatigue_text, fatigue_rect, shadow_text, shadow_rect = load_shadow_text("Fatigue: %i" % self.player.fatigue, self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + self.text_spacing) self.screen.blit(shadow_text, shadow_rect) hunger_text, hunger_rect, shadow_text, shadow_rect = load_shadow_text("Hunger: %i" % self.player.hunger, self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 2)) self.screen.blit(shadow_text, shadow_rect) thirst_text, thirst_rect, shadow_text, shadow_rect = load_shadow_text("Thirst: %i" % self.player.thirst, self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 3)) self.screen.blit(shadow_text, shadow_rect) weight_text, weight_rect, shadow_text, shadow_rect = load_shadow_text("Weight: %i" % self.player.weight, self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 4)) self.screen.blit(shadow_text, shadow_rect) strength_text, strength_rect, shadow_text, shadow_rect = load_shadow_text("Strength: %i" % self.player.GetStrength(), self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 6)) self.screen.blit(shadow_text, shadow_rect) speed_text, speed_rect, shadow_text, shadow_rect = load_shadow_text("Speed: %i" % self.player.GetSpeed(), self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 7)) self.screen.blit(shadow_text, shadow_rect) accuracy_text, accuracy_rect, shadow_text, shadow_rect = load_shadow_text("Accuracy: %i" % self.player.GetAccuracy(), self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 8)) self.screen.blit(shadow_text, shadow_rect) concentration_text, concentration_rect, shadow_text, shadow_rect = load_shadow_text("Concentration: %i" % self.player.GetConcentration(), self.stat_font, (255,255,255), print_x + self.margin, print_y + self.margin + (self.text_spacing * 9)) self.screen.blit(shadow_text, shadow_rect) fps_text, fps_rect = load_text("TURNS: %i, FPS: %i" % (self.player.age, self.clock.get_fps()), self.fps_font, (255,255,255), 0, 0) self.screen.blit(wounds_text, wounds_rect) self.screen.blit(fatigue_text, fatigue_rect) self.screen.blit(hunger_text, hunger_rect) self.screen.blit(thirst_text, thirst_rect) self.screen.blit(weight_text, weight_rect) self.screen.blit(strength_text, strength_rect) self.screen.blit(speed_text, speed_rect) self.screen.blit(accuracy_text, accuracy_rect) self.screen.blit(concentration_text, concentration_rect) self.screen.blit(fps_text, fps_rect) # command display command_x = self.width - self.margin - self.sidebar_width command_y = self.margin bg_surface = pygame.Surface((self.sidebar_width, self.height - mini_map_height - self.margin * 3)) bg_surface.fill((255,0,0)) bg_surface.set_alpha(self.sidebar_alpha) bg_rect = pygame.Rect(command_x, command_y, self.sidebar_width, self.height - mini_map_height - self.margin * 3) self.screen.blit(bg_surface, bg_rect) item_count = 0 if len(self.current_items) > 0: # items items_text, items_rect, shadow_text, shadow_rect = load_shadow_text("Items:", self.stat_font, (255,255,255), command_x + self.margin, command_y + self.margin) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(items_text, items_rect) for item in self.current_items: if (item_count >= 10): break item_text, item_rect, shadow_text, shadow_rect = load_shadow_text("%(count)i: %(description)s" % {"count":item_count, "description":item.GetName()}, self.event_font, (255,255,0), command_x + self.margin, command_y + self.margin + self.text_spacing + self.event_spacing * item_count) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(item_text, item_rect) item_count += 1 if self.current_action == self.action_move: command_text, command_rect, shadow_text, shadow_rect = load_shadow_text("Enter direction to move", self.stat_font, (255,255,255), command_x + self.margin, command_y + self.margin + self.text_spacing * 2 + self.event_spacing * item_count) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(command_text, command_rect) elif self.current_action == self.action_push: command_text, command_rect, shadow_text, shadow_rect = load_shadow_text("Enter direction to push", self.stat_font, (255,255,255), command_x + self.margin, command_y + self.margin + self.text_spacing * 2 + self.event_spacing * item_count) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(command_text, command_rect) elif self.current_action == self.action_attack: command_text, command_rect, shadow_text, shadow_rect = load_shadow_text("Enter direction to attack", self.stat_font, (255,255,255), command_x + self.margin, command_y + self.margin + self.text_spacing * 2 + self.event_spacing * item_count) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(command_text, command_rect) log_surface = pygame.Surface((self.view_width - self.margin * 3 - self.sidebar_width, self.sidebar_width)) log_surface.fill((255,0,0)) log_surface.set_alpha(self.log_alpha) log_rect = pygame.Rect(self.margin, self.view_height - self.sidebar_width - self.margin, self.view_width - self.margin, self.sidebar_width - self.margin) self.screen.blit(log_surface, log_rect) # event display event_count = 0 for event in self.log.events: if (event_count >= 12): break event_bg_text, event_bg_rect = load_text(event, self.event_font, (0,0,0), (self.margin * 2) + 1, (self.view_height - self.sidebar_width - self.margin) + (self.margin + self.event_spacing * event_count) + 1) self.screen.blit(event_bg_text, event_bg_rect) event_text, event_rect = load_text(event, self.event_font, (255,255,0), self.margin * 2, (self.view_height - self.sidebar_width - self.margin) + (self.margin + self.event_spacing * event_count)) self.screen.blit(event_text, event_rect) event_count += 1 self.RefreshMouse() target_count = 0 for target in self.mouse_targets: target_text, target_rect, shadow_text, shadow_rect = load_shadow_text(target, self.event_font, (255,255,255), self.mouse_pos[0] + self.event_spacing, self.mouse_pos[1] + self.event_spacing + (self.event_spacing * target_count)) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(target_text, target_rect) target_count += 1 pygame.display.flip() if self.player.IsDead(): self.ShowDeathScreen() def GetTargetAt(self, tile): target = None for actor in self.board.actors: if actor.pos_x == tile[0] and actor.pos_y == tile[1] and actor != self.player: target = actor break return target def RefreshMouse(self): if self.mouse_pos is not None: self.mouse_targets = self.board.GetTargetsAt(self.view_width, self.view_height, self.player, self.mouse_pos) def ShowDeathScreen(self): self.Delete() while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: self.Exit(False) bg_surface = pygame.Surface((self.width - (self.sidebar_width * 2) - (self.margin * 4), self.height - (self.sidebar_width * 2) - (self.margin * 4))) bg_surface.fill((150,0,0)) bg_surface.set_alpha(self.sidebar_alpha) bg_rect = pygame.Rect(self.sidebar_width + self.margin * 2, self.sidebar_width + self.margin * 2, self.width - (self.sidebar_width * 2) - (self.margin * 4), self.height - (self.sidebar_width * 2) - (self.margin * 4)) self.screen.blit(bg_surface, bg_rect) dead_text, dead_rect, shadow_text, shadow_rect = load_shadow_text("You are DEAD", self.stat_font, (255,255,255), self.sidebar_width + self.margin * 4, self.sidebar_width + self.margin * 4) self.screen.blit(shadow_text, shadow_rect) self.screen.blit(dead_text, dead_rect) pygame.display.flip() def ShowInventoryScreen(self): stay = True action_drop = 0 action_equip = 1 action_consume = 2 current_action = None while stay: for event in pygame.event.get(): if event.type == pygame.QUIT: self.Exit() elif event.type == KEYDOWN: action = None selected_index = None if (event.key == K_ESCAPE): stay = False elif (event.key == K_0): selected_index = 0 elif (event.key == K_1): selected_index = 1 elif (event.key == K_2): selected_index = 2 elif (event.key == K_3): selected_index = 3 elif (event.key == K_4): selected_index = 4 elif (event.key == K_5): selected_index = 5 elif (event.key == K_6): selected_index = 6 elif (event.key == K_7): selected_index = 7 elif (event.key == K_8): selected_index = 8 elif (event.key == K_9): selected_index = 9 elif (event.key == K_d): action = action_drop elif (event.key == K_e): action = action_equip elif (event.key == K_c): action = action_consume elif (event.key == K_u): self.player.RemoveWeapon() elif (event.key == K_t): self.player.RemoveArmor() if current_action is not None and selected_index is not None: if current_action == action_drop: self.DropItem(selected_index) elif current_action == action_equip: self.player.EquipItem(selected_index) elif current_action == action_consume: self.player.ConsumeItem(selected_index) elif action is None: current_action = None else: current_action = action elif event.type == pygame.VIDEORESIZE: self.SetSizes(event.dict['size']) listing_x = self.margin * 5 listing_y = self.margin * 5 listing_width = self.width - self.margin * 10 listing_height = self.height - self.margin * 10 bg_surface = pygame.Surface((listing_width, listing_height)) bg_surface.fill((30,30,30)) bg_rect = pygame.Rect(listing_x, listing_y, listing_width, listing_height) self.screen.blit(bg_surface, bg_rect) items_text, items_rect = load_text("Carrying:", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin) self.screen.blit(items_text, items_rect) item_count = 0 for item in self.player.items: item_text, item_rect = load_text("%(count)i: %(description)s" % {"count":item_count, "description":item.GetName()}, self.event_font, (255,255,0), listing_x + self.margin, listing_y + self.margin + self.text_spacing + self.event_spacing * item_count) self.screen.blit(item_text, item_rect) item_count += 1 weapon = "Unarmed" armor = "Clothes" if self.player.weapon is not None: weapon = self.player.weapon.GetName() if self.player.armor is not None: armor = self.player.armor.GetName() weapon_text, weapon_rect = load_text("Weapon: %s" % weapon, self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 2 + self.event_spacing * item_count) self.screen.blit(weapon_text, weapon_rect) armor_text, armor_rect = load_text("Armor: %s" % armor, self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 3 + self.event_spacing * item_count) self.screen.blit(armor_text, armor_rect) command_text, command_rect = load_text("Commands:", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 5 + self.event_spacing * item_count) self.screen.blit(command_text, command_rect) command_text, command_rect = load_text("E,#: Equip item number #", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 6 + self.event_spacing * item_count) self.screen.blit(command_text, command_rect) command_text, command_rect = load_text("D,#: Drop item number #", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 7 + self.event_spacing * item_count) self.screen.blit(command_text, command_rect) command_text, command_rect = load_text("C,#: Consume item number #", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 8 + self.event_spacing * item_count) self.screen.blit(command_text, command_rect) command_text, command_rect = load_text("U: Unweild current weapon", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 9 + self.event_spacing * item_count) self.screen.blit(command_text, command_rect) command_text, command_rect = load_text("T: Take off current armor", self.stat_font, (255,255,255), listing_x + self.margin, listing_y + self.margin + self.text_spacing * 10 + self.event_spacing * item_count) self.screen.blit(command_text, command_rect) pygame.display.flip() def ProcessTurn(self): self.board.CalculateLineOfSight(self.player) kill_stack = [] add_stack = [] for actor in self.board.actors: actor.Age() actor.CheckTargets(self.board) if actor.action_debt == 0: if isinstance(actor, Npc): if actor.target_actor is not None and actor.IsAggressive(actor.target_actor): self.AttackTarget(actor, actor.target_actor) elif not self.DoBarricades(actor): actor.Move(self.board) for actor in self.board.actors: if actor.IsDead(): kill_stack.append(actor) if self.board.IsVisible(actor.pos_x, actor.pos_y): self.log.Push("%s was killed" % actor.GetName()) if isinstance(actor, Human) and actor.infected: add_stack.append(Zombie(actor.pos_x, actor.pos_y)) if self.board.IsVisible(actor.pos_x, actor.pos_y): self.log.Push("%s stood back up" % actor.GetName()) for actor in kill_stack: #self.board.features.append((actor.pos_x, actor.pos_y, self.board.feature_blood, "Blood splatter")) self.board.actors.remove(actor) for actor in add_stack: self.board.actors.append(actor) self.current_items = [] for item in self.board.items: if item[0] == self.player.pos_x and item[1] == self.player.pos_y: self.current_items.append(item[2]) def Move(self, key): xMove = 0 yMove = 0 if (key == K_RIGHT): xMove = 1 elif (key == K_LEFT): xMove = -1 elif (key == K_UP): yMove = -1 elif (key == K_DOWN): yMove = 1 dest_x = self.player.pos_x + xMove dest_y = self.player.pos_y + yMove return self.MoveTo(dest_x, dest_y) def MoveTo(self, dest_x, dest_y): xMove = dest_x - self.player.pos_x yMove = dest_y - self.player.pos_y if abs(xMove) + abs(yMove) > 1: return False else: if dest_x < 0 or dest_x >= self.board.width or dest_y < 0 or dest_y >= self.board.height: new_board = None board_x = 0 board_y = 0 for yy in xrange(0, len(self.meta_board)): for xx in xrange(0, len(self.meta_board[yy])): if self.meta_board[yy][xx] == self.board.board_id: board_x = xx board_y = yy break if dest_x < 0: # moving board West self.player.pos_x = self.board.width - 1 board_x -= 1 if dest_x == self.board.width: # moving board East self.player.pos_x = 0 board_x += 1 if dest_y < 0: # moving board North self.player.pos_y = self.board.height - 1 board_y -= 1 if dest_y == self.board.width: # moving board South self.player.pos_y = 0 board_y += 1 if board_y < 0: # need to expand meta board north self.meta_board.insert(0, []) for xx in xrange(0, len(self.meta_board[board_y])): self.meta_board[0].append(None) board_y += 1 if board_y == len(self.meta_board): # need to expand meta board south self.meta_board.append([]) for xx in xrange(0, len(self.meta_board[board_y - 1])): self.meta_board[board_y].append(None) if board_x < 0: # need to expand meta board west for yy in xrange(0, len(self.meta_board)): self.meta_board[yy].insert(0, None) board_x += 1 if board_x == len(self.meta_board[board_y]): # need to expand meta board east for yy in xrange(0, len(self.meta_board)): self.meta_board[yy].append(None) if self.meta_board[board_y][board_x] is None: ter = random.randint(0, 2) if ter == 0: new_board = Board('Suburb') elif ter == 1: new_board = Board('City') else: new_board = Board('Rural') self.meta_board[board_y][board_x] = new_board.board_id else: new_board = self.LoadBoard(self.meta_board[board_y][board_x]) self.SaveBoard(self.board) self.board = new_board self.player.board_id = new_board.board_id self.Save() return True else: return self.player.Move(xMove, yMove, self.board) def PushTarget(self, predator, prey): pushed = False xMove = prey.pos_x - predator.pos_x yMove = prey.pos_y - predator.pos_y if self.board.CanMove(prey, prey.pos_x + xMove, prey.pos_y + yMove): prey.pos_x += xMove prey.pos_y += yMove pushed = True self.log.Push('%(predator)s pushed %(prey)s' % {'predator':predator.GetName(), 'prey':prey.GetName()}) else: self.log.Push('%(predator)s failed to push %(prey)s' % {'predator':predator.GetName(), 'prey':prey.GetName()}) if pushed: predator.action_debt += predator.action_debt_push return pushed def MoveCrosshair(self, key): xMove = 0 yMove = 0 if (key == K_RIGHT): xMove = 1 elif (key == K_LEFT): xMove = -1 elif (key == K_UP): yMove = -1 elif (key == K_DOWN): yMove = 1 dest_x = self.crosshair_pos[0] + xMove dest_y = self.crosshair_pos[1] + yMove weapon_reach = 1 if self.player.weapon is not None: weapon_reach = self.player.weapon.reach dist = ((self.player.pos_x - dest_x) ** 2) + ((self.player.pos_y - dest_y) ** 2) reach = weapon_reach ** 2 if dist < reach and dest_x >= 0 and dest_x < self.board.width and dest_y >= 0 and dest_y < self.board.height and self.board.IsVisible(dest_x, dest_y): self.crosshair_pos = (dest_x, dest_y) def RangeAttack(self, predator, point): attacked = False weapon_reach = 1 if predator.weapon is not None: weapon_reach = predator.weapon.reach dist = ((predator.pos_x - point[0]) ** 2) + ((predator.pos_y - point[1]) ** 2) reach = weapon_reach ** 2 if dist <= reach: for actor in self.board.actors: if actor.pos_x == point[0] and actor.pos_y == point[1] and actor != predator: attacked = self.AttackTarget(predator, actor) break return attacked def AttackTarget(self, predator, prey): attacked = True if predator.Attack(prey): damage = random.randrange(0, predator.GetMaxDamage(), 1) prey.wounds += damage if isinstance(predator, Zombie): prey.infected = True if self.board.IsVisible(predator.pos_x, predator.pos_y) or self.board.IsVisible(prey.pos_x, prey.pos_y): self.log.Push('%(predator)s attacked %(prey)s for %(damage)i damage' % {'predator':predator.GetName(), 'prey':prey.GetName(), 'damage':damage}) else: if self.board.IsVisible(predator.pos_x, predator.pos_y) or self.board.IsVisible(prey.pos_x, prey.pos_y): self.log.Push('%(predator)s missed %(prey)s' % {'predator':predator.GetName(), 'prey':prey.GetName()}) if attacked: predator.action_debt += predator.action_debt_attack if isinstance(predator, Player) and isinstance(prey, Human): prey.hostile = True return attacked def DoBarricades(self, actor): did_barricades = actor.DoBarricades(self.board) if did_barricades: actor.action_debt += actor.action_debt_barricade self.log.Push("%s destroyed a barricade" % actor.GetName()) return did_barricades def OpenOrCloseDoor(self, key): opened_or_closed = False xMove = 0 yMove = 0 if (key == K_RIGHT): xMove = 1 elif (key == K_LEFT): xMove = -1 elif (key == K_UP): yMove = -1 elif (key == K_DOWN): yMove = 1 if self.board.TryOpen(self.player.pos_x + xMove, self.player.pos_y + yMove): self.log.Push("You opened the door") opened_or_closed = True elif self.board.TryClose(self.player.pos_x + xMove, self.player.pos_y + yMove): self.log.Push("You closed the door") opened_or_closed = True else: self.log.Push("Open/Close door failed") return opened_or_closed def Barricade(self, key): barricaded = False xMove = 0 yMove = 0 if (key == K_RIGHT): xMove = 1 elif (key == K_LEFT): xMove = -1 elif (key == K_UP): yMove = -1 elif (key == K_DOWN): yMove = 1 if self.board.TryBarricade(self.player.pos_x + xMove, self.player.pos_y + yMove): self.log.Push("Barricaded") barricaded = True else: self.log.Push("Couldn't barricade there") return barricaded def Unbarricade(self, key): xMove = 0 yMove = 0 if (key == K_RIGHT): xMove = 1 elif (key == K_LEFT): xMove = -1 elif (key == K_UP): yMove = -1 elif (key == K_DOWN): yMove = 1 return UnbarricadeAt(self.player.pos_x + xMove, self.player.pos_y + yMove) def UnbarricadeAt(self, dest_x, dest_y): unbarricaded = False if self.board.TryUnbarricade(dest_x, dest_y): self.log.Push("Barricade removed") unbarricaded = True else: self.log.Push("Couldn't remove barricade") return unbarricaded def GetItem(self, index): if len(self.current_items) > index: the_item = self.current_items[index] self.current_items.remove(the_item) self.player.AppendItem(the_item) self.log.Push("Got %s" % the_item.GetName()) for item in self.board.items: if item[2] == the_item: self.board.items.remove(item) break else: self.log.Push("There is no item %i here." % index) def DropItem(self, index): if len(self.player.items) > index: the_item = self.player.items[index] self.player.RemoveItem(the_item) self.current_items.append(the_item) self.board.items.append((self.player.pos_x, self.player.pos_y, the_item)) def Rest(self): events = len(self.log.events) while self.player.fatigue > 0: self.player.Rest() self.ProcessTurn() if len(self.log.events) != events: self.log.Push("Rest interrupted!") break if self.player.fatigue == 0: self.log.Push("Rest complete") self.Save() def Exit(self, save = True): if save: self.Save() sys.exit() def Delete(self): top = os.path.join('data', 'saves') for root, dirs, files in os.walk(top, topdown=False): for name in files: split_name = os.path.splitext(name) if split_name[len(split_name) - 1] == '.dat': os.remove(os.path.join(root, name)) def Save(self): player_file = file(os.path.join('data', 'saves', 'player.dat'), 'wb') pickle.dump(self.player, player_file, False) player_file.close() meta_board_file = file(os.path.join('data', 'saves', 'meta_board.dat'), 'wb') pickle.dump(self.meta_board, meta_board_file, False) meta_board_file.close() self.SaveBoard(self.board) self.log.Push("Game saved.") self.Load() def SaveBoard(self, board): board_file = file(os.path.join('data', 'saves', 'board_%s.dat' % board.board_id), 'wb') pickle.dump(board, board_file, False) board_file.close() def Load(self): player_file = file(os.path.join('data', 'saves', 'player.dat'), 'rb') self.player = pickle.load(player_file) meta_board_file = file(os.path.join('data', 'saves', 'meta_board.dat'), 'rb') self.meta_board = pickle.load(meta_board_file) self.board = self.LoadBoard(self.player.board_id) # reference to player will have been lost, reset it for actor in self.board.actors: if isinstance(actor, Player): self.board.actors.remove(actor) elif actor.target_actor is not None and isinstance(actor.target_actor, Player): actor.target_actor = self.player self.board.actors.append(self.player) def LoadBoard(self, board_id): board_file = file(os.path.join('data', 'saves', 'board_%s.dat' % board_id), 'rb') return pickle.load(board_file) if __name__ == "__main__": MainWindow = ZedZedMain(800, 600) MainWindow.MainLoop() """ import types all_vars = vars(sys.modules["Items"]) for var in all_vars: var_type = type(all_vars[var]) if var_type is types.TypeType: print "%s: %s" % (var_type, var) """