""" 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 pygame import random from pygame.sprite import Sprite from helpers import * from Actors import * from Items import * from Features import * import math class Board(object): def __init__(self, terrain): # constants self.board_floor = 0 self.board_grass = 2 self.board_road = 3 self.board_concrete = 4 self.board_grass_floor_e = 5 self.board_grass_floor_n = 6 self.board_grass_floor_ne = 7 self.board_grass_floor_nw = 8 self.board_grass_floor_s = 9 self.board_grass_floor_se = 10 self.board_grass_floor_sw = 11 self.board_grass_floor_w = 12 self.los_unseen = -1 self.los_seen = 0 self.los_visible = 1 self.path_yes = 0 self.path_no = 1 self.vis_yes = 0 self.vis_no = 1 self.feature_blood = 3 self.deco_floor = 0 self.deco_grass = 1 self.deco_wall_ew = 2 self.deco_wall_ns = 3 self.deco_block_floor = 4 self.deco_block_grass = 5 self.deco_obj_floor = 6 self.deco_obj_grass = 7 self.deco_storage_floor = 8 self.deco_floor_count = 16 self.deco_grass_count = 3 self.deco_wall_count = 22 self.block_grass_count = 1 self.obj_floor_count = 7 self.obj_grass_count = 1 self.storage_floor_count = 9 self.terrain_suburb = 'Suburb' self.terrain_city = 'City' self.terrain_rural = 'Rural' # members self.terrain = terrain self.board_id = ''.join(random.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 4)) """ if board_north is None: self.board_north = None else: self.board_north = board_north.board_id if board_south is None: self.board_south = None else: self.board_south = board_south.board_id if board_east is None: self.board_east = None else: self.board_east = board_east.board_id if board_west is None: self.board_west = None else: self.board_west = board_west.board_id """ # todo: line up roads self.board = [] self.terrain_board = [] self.overlay_board = [] self.object_board = [] self.los_board = [] self.path_board = [] self.vis_board = [] self.decorations = [] self.rooms = [] #self.features = [] self.barricades = [] self.actors = [] self.items = [] # description, weight, protection self.armors = [("Poncho", 2, 1), ("Cardboard Box", 3, 2), ("Sweater", 5, 3), ("Windbreaker", 5, 4), ("Leather Jacket", 10, 5), ("Kevlar Jacket", 20, 6), ("Riot Gear", 50, 7)] # description, weight, damage, accuracy, reach, volume self.weapons = [("Fork", 1, 1, 1, 1, 0), ("Knife", 1, 2, 2, 1, 0), ("Hammer", 5, 3, 3, 1, 0), ("Baseball Bat", 10, 4, 2, 1, 1), ("Crowbar", 5, 5, 5, 1, 1), ("Katana", 20, 6, 8, 1, 1), ("Axe", 30, 7, 4, 1, 3), ("Sledgehammer", 50, 8, 2, 1, 5)] # (description, weight, damage, accuracy, reach, volume, caliber), (description, weight, caliber, quantity) self.loadable_weapons = [[("Bow", 10, 5, 5, 6, 5, "arrow"), ("Arrow", 1, "arrow", 12)], [("Crossbow", 7, 3, 6, 8, 2, "bolt"), ("Crossbow Bolt", 1, "bolt", 20)], [("Handgun", 3, 10, 10, 20, 40, "9mm"), ("9mm bullet", 1, "9mm", 20)], [("Shotgun", 5, 30, 10, 10, 60, "shell"), ("Shotgun shell", 1, "shell", 12)]] # description, weight, hunger, thirst self.foods = [("Apple", 1, 1, 1), ("Banana", 1, 2, 0), ("Chips", 2, 3, 0), ("Sandwich", 2, 4, 0), ("Snack cake", 2, 5, 0), ("Pie", 5, 6, 0), ("Cake", 5, 7, 0), ("Water", 2, 0, 10), ("Juice", 2, 2, 4), ("Tea", 2, 1, 3), ("Soda", 2, 2, 2), ("Diet Soda", 2, 0, 2)] # description, city_chance, suburb_chance, min_size, max_size, armor, weapons, loadable_weapons, food self.buildings = [("Shed", 5, 10, 3, 5, 2.0, 5.0, 1.0, 0.0), ("House", 10, 20, 3, 10, 1.0, 1.0, 0.4, 3.0), ("Apartment Building", 20, 10, 10, 20, 0.4, 0.4, 1.0, 2.0), ("Corner Store", 20, 10, 3, 10, 0.5, 0.5, 0.3, 10.0), ("Grocery Store", 5, 10, 10, 50, 0.2, 0.2, 0.1, 5.0), ("Hardware Store", 20, 20, 10, 20, 1.0, 2.0, 0.5, 0.1), ("Gun Store", 5, 20, 5, 10, 0.5, 0.5, 5.0, 0.1), ("Police Station", 10, 10, 10, 20, 2.0, 0.5, 5.0, 0.5), ("Industry", 10, 10, 10, 30, 0.5, 0.5, 0.2, 0.2)] self.building_prefixes = ["Bob's ", "Crazy Joe's ", "Mad Max's ", "Tom's ", "Willard ", "Willamette ", "Baltimore ", "New York ", "Smith's ", "Jones' ", "Ben's ", "Zed's "] self.width = 100 self.height = 100 self.tile_width = 52 self.tile_height = 26 self.LoadImages() if self.terrain == self.terrain_suburb: self.GenerateSuburb() elif self.terrain == self.terrain_city: self.GenerateCity() elif self.terrain == self.terrain_rural: self.GenerateRural() else: print "error" sys.exit() #print "board done" def AddRoad(self, road_width, pos_x, pos_y, horizontal=True, windy=True): if horizontal: # split board horizontally for xx in xrange(0, self.width): if windy and random.randint(0, 10) == 0: pos_y += random.randrange(-1, 2, 1) if pos_y < 1: pos_y = 1 elif pos_y > self.height - 1: pos_y = self.height - 1 for yy in xrange(pos_y, pos_y + road_width): self.board[yy][xx] = self.board_road else: # split board vertically for yy in xrange(0, self.height): if windy and random.randint(0, 10) == 0: pos_x += random.randrange(-1, 2, 1) if pos_x < 1: pos_x = 1 elif pos_x > self.width - 1: pos_x = self.width - 1 for xx in xrange(pos_x, pos_x + road_width): self.board[yy][xx] = self.board_road def AddBuilding(self, board_type, min_width=None, min_height=None, max_width=None, max_height=None, floor=None): if min_height is None: min_height = 3 if min_width is None: min_width = 3 if max_height is None: max_height = self.height if max_width is None: max_width = self.width if floor is None: floor = self.board_floor room_invalid = True building_type = None while building_type == None: building_type = self.buildings[random.randint(0, len(self.buildings) - 1)] chance = 0 if board_type == self.terrain_suburb: chance = building_type[2] elif board_type == self.terrain_city: chance = building_type[1] elif board_type == self.terrain_rural: chance = building_type[2] if random.randint(0, 100) > chance: building_type = None max_height = min(max_height, building_type[4]) max_width = min(max_width, building_type[4]) min_height = max(min_height, building_type[3]) min_width = max(min_width, building_type[3]) building_description = self.building_prefixes[random.randint(0, len(self.building_prefixes) - 1)] + building_type[0] #if max_height >= min_height and max_width >= min_width: room_tries = 0 while room_invalid and room_tries < 100: # get top left coordinates of room # skipping anything too far into the bottom right to fit room_x = random.randint(1, self.width - (min_width + 2) - 1) room_y = random.randint(1, self.height - (min_height + 2) - 1) # get width and height of at least 3, but constrain max to what will fit room_width = random.randint(min_width, min(max_width, self.width - room_x - 2)) room_height = random.randint(min_height, min(max_height, self.height - room_y - 2)) # don't make stupid skinny buildings if room_width <= room_height * 2 and room_height <= room_width * 2: # it's okay room_invalid = False # check if any overlap inside the room or adjacent for xx in xrange(room_x - 1, room_x + room_width + 2): for yy in xrange(room_y - 1, room_y + room_height + 2): if self.terrain_board[yy][xx] is not None or self.board[yy][xx] == self.board_road or self.IsInside(xx, yy): # overlap or inside, skip it room_invalid = True break if room_invalid: break room_tries += 1 if room_invalid == False: #print "placing %s, %i x %i" % (building_description, room_width, room_height) # top & bottom walls for xx in xrange(room_x, room_x + room_width + 1): self.terrain_board[room_y][xx] = Wall() self.terrain_board[room_y + room_height][xx] = Wall() self.path_board[room_y][xx] = self.path_no self.path_board[room_y + room_height][xx] = self.path_no self.vis_board[room_y][xx] = self.vis_no self.vis_board[room_y + room_height][xx] = self.vis_no # left & right walls for yy in xrange(room_y, room_y + room_height + 1): self.terrain_board[yy][room_x] = Wall() self.terrain_board[yy][room_x + room_width] = Wall() self.path_board[yy][room_x] = self.path_no self.path_board[yy][room_x + room_width] = self.path_no self.vis_board[yy][room_x] = self.vis_no self.vis_board[yy][room_x + room_width] = self.vis_no """ # edges self.board[room_y][room_x] = self.board_grass_floor_nw self.board[room_y][room_x + room_width] = self.board_grass_floor_ne self.board[room_y + room_height][room_x] = self.board_grass_floor_sw self.board[room_y + room_height][room_x + room_width] = self.board_grass_floor_se for yy in xrange(room_y + 1, room_y + room_height): self.board[yy][room_x] = self.board_grass_floor_w self.board[yy][room_x + room_height] = self.board_grass_floor_e for xx in xrange(room_x + 1, room_x + room_width): self.board[room_y][xx] = self.board_grass_floor_n self.board[room_y + room_width][xx] = self.board_grass_floor_s """ # floor #for yy in xrange(room_y + 1, room_y + room_height): # for xx in xrange(room_x + 1, room_x + room_width): for yy in xrange(room_y, room_y + room_height + 1): for xx in xrange(room_x, room_x + room_width + 1): self.board[yy][xx] = floor #if room_y < yy < room_y + room_height and room_x < xx < room_x + room_width: # # clear out the inside # self.path_board[yy][xx] = self.path_yes # self.vis_board[yy][xx] = self.vis_yes doors = random.randint(1, max(room_width * room_height / 35, 1)) #print "%i doors" % doors for door_count in xrange(0, doors): door_tries = 0 door_invalid = True while door_invalid and door_tries < 100: side = random.randint(0, 3) door_x = 0 door_y = 0 #feature = None direction = None if side == 0: # top door_x = random.randint(room_x + 1, room_x + room_width - 1) door_y = room_y if room_y > 0 and self.vis_board[door_y - 1][door_x] == self.vis_yes and self.vis_board[door_y + 1][door_x] == self.vis_yes: door_invalid = False #feature = self.feature_door_closed_ew #direction = Feature.DIRECTION_EW elif side == 1: # bottom door_x = random.randint(room_x + 1, room_x + room_width - 1) door_y = room_y + room_height if room_y + room_height < self.height - 1 and self.vis_board[door_y - 1][door_x] == self.vis_yes and self.vis_board[door_y + 1][door_x] == self.vis_yes: door_invalid = False #feature = self.feature_door_closed_ew #direction = Feature.DIRECTION_EW elif side == 2: # left door_x = room_x door_y = random.randint(room_y + 1, room_y + room_height - 1) if room_x > 0 and self.vis_board[door_y][door_x - 1] == self.vis_yes and self.vis_board[door_y][door_x + 1] == self.vis_yes: door_invalid = False #feature = self.feature_door_closed_ns #direction = Feature.DIRECTION_NS elif side == 3: # right door_x = room_x + room_width door_y = random.randint(room_y + 1, room_y + room_height - 1) if room_x + room_width < self.width - 1 and self.vis_board[door_y][door_x - 1] == self.vis_yes and self.vis_board[door_y][door_x + 1] == self.vis_yes: door_invalid = False #feature = self.feature_door_closed_ns #direction = Feature.DIRECTION_NS """ if not door_invalid: # don't draw a door over another door or window door_invalid = self.terrain_board[door_y][door_x] is None """ if not door_invalid: #self.board[door_y][door_x] = self.board_floor #self.terrain_board[door_y][door_x] = feature #self.features.append((door_x, door_y, feature, "Door (%s)" % building_description)) #door = Door(building_description, door_x, door_y, direction) #self.features.append(door) #self.terrain_board[door_y][door_x] = Door(building_description, direction) self.terrain_board[door_y][door_x].AddDoor(building_description) door_tries += 1 self.BisectRoom(room_x, room_y, room_width, room_height) #print "bisected" windows = random.randint(1, max(room_width * room_height / 25, 1)) #print "%i windows" % windows for window_count in xrange(0, windows): window_tries = 0 window_invalid = True while window_invalid and window_tries < 100: side = random.randint(0, 3) window_x = 0 window_y = 0 #feature = None direction = None if side == 0: # top window_x = random.randint(room_x + 1, room_x + room_width - 1) window_y = room_y if room_y > 0 and self.vis_board[window_y - 1][window_x] == self.vis_yes and self.vis_board[window_y + 1][window_x] == self.vis_yes: window_invalid = False #feature = self.feature_window_ew #direction = Feature.DIRECTION_EW elif side == 1: # bottom window_x = random.randint(room_x + 1, room_x + room_width - 1) window_y = room_y + room_height if room_y + room_height < self.height - 1 and self.vis_board[window_y - 1][window_x] == self.vis_yes and self.vis_board[window_y + 1][window_x] == self.vis_yes: window_invalid = False #feature = self.feature_window_ew #direction = Feature.DIRECTION_EW elif side == 2: # left window_x = room_x window_y = random.randint(room_y + 1, room_y + room_height - 1) if room_x > 0 and self.vis_board[window_y][window_x - 1] == self.vis_yes and self.vis_board[window_y][window_x + 1] == self.vis_yes: window_invalid = False #feature = self.feature_window_ns #direction = Feature.DIRECTION_NS elif side == 3: # left window_x = room_x + room_width window_y = random.randint(room_y + 1, room_y + room_height - 1) if room_x + room_width < self.width - 1 and self.vis_board[window_y][window_x - 1] == self.vis_yes and self.vis_board[window_y][window_x + 1] == self.vis_yes: window_invalid = False #feature = self.feature_window_ns #direction = Feature.DIRECTION_NS """ if not window_invalid: # don't draw a window over a wall gap (like a door) window_invalid = not isinstance(self.terrain_board[window_y][window_x], Wall) """ if not window_invalid: self.vis_board[window_y][window_x] = self.vis_yes #self.board[window_y][window_x] = self.board_floor #self.features.append((window_x, window_y, feature, "Window (%s)" % building_description)) self.terrain_board[window_y][window_x].AddWindow(building_description) window_tries += 1 self.rooms.append((building_description, building_type, room_x, room_y, room_width, room_height)) def MatchTiles(self): for yy in range(0, self.height): for xx in range(0, self.width): if self.board[yy][xx] == self.board_floor: grass_n = False grass_s = False grass_e = False grass_w = False if yy > 0 and self.board[yy - 1][xx] == self.board_grass: grass_n = True if yy < self.height and self.board[yy + 1][xx] == self.board_grass: grass_s = True if xx > 0 and self.board[yy][xx - 1] == self.board_grass: grass_w = True if xx < self.width and self.board[yy][xx + 1] == self.board_grass: grass_e = True if grass_n and grass_s and grass_e and grass_w: self.board[yy][xx] = self.board_floor elif grass_e and grass_s and grass_w: self.board[yy][xx] = self.board_floor elif grass_n and grass_e and grass_s: self.board[yy][xx] = self.board_floor elif grass_n and grass_e and grass_w: self.board[yy][xx] = self.board_floor elif grass_n and grass_s and grass_w: self.board[yy][xx] = self.board_floor elif grass_e and grass_s: self.board[yy][xx] = self.board_grass_floor_se elif grass_e and grass_w: self.board[yy][xx] = self.board_floor elif grass_n and grass_e: self.board[yy][xx] = self.board_grass_floor_ne elif grass_n and grass_s: self.board[yy][xx] = self.board_floor elif grass_n and grass_w: self.board[yy][xx] = self.board_grass_floor_nw elif grass_s and grass_w: self.board[yy][xx] = self.board_grass_floor_sw elif grass_e: self.board[yy][xx] = self.board_grass_floor_e elif grass_n: self.board[yy][xx] = self.board_grass_floor_n elif grass_s: self.board[yy][xx] = self.board_grass_floor_s elif grass_w: self.board[yy][xx] = self.board_grass_floor_w if isinstance(self.terrain_board[yy][xx], Wall): wall_n = False wall_s = False wall_e = False wall_w = False if yy > 0 and self.terrain_board[yy - 1][xx] is not None: wall_n = True if yy < self.height and self.terrain_board[yy + 1][xx] is not None: wall_s = True if xx > 0 and self.terrain_board[yy][xx - 1] is not None: wall_w = True if xx < self.width and self.terrain_board[yy][xx + 1] is not None: wall_e = True if wall_n and wall_s and wall_e and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NESW elif wall_e and wall_s and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_ESW elif wall_n and wall_e and wall_s: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NES elif wall_n and wall_e and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NEW elif wall_n and wall_s and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NSW elif wall_e and wall_s: self.terrain_board[yy][xx].direction = Feature.DIRECTION_ES elif wall_e and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_EW elif wall_n and wall_e: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NE elif wall_n and wall_s: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NS elif wall_n and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_NW elif wall_s and wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_SW elif wall_e: self.terrain_board[yy][xx].direction = Feature.DIRECTION_E elif wall_n: self.terrain_board[yy][xx].direction = Feature.DIRECTION_N elif wall_s: self.terrain_board[yy][xx].direction = Feature.DIRECTION_S elif wall_w: self.terrain_board[yy][xx].direction = Feature.DIRECTION_W self.terrain_board[yy][xx].RefreshImage() def Populate(self, terrain): # add the survivors count = self.width * self.height / 400; if terrain == self.terrain_city: count = count * 2 elif terrain == self.terrain_rural: count = count / 2 for ii in range(0, int(count)): pos_x = 0 pos_y = 0 while self.CanMove(None, pos_x, pos_y) == False or self.IsInside(pos_x, pos_y) == False: pos_x = random.randint(0, self.width - 1) pos_y = random.randint(0, self.height - 1) self.actors.append(Survivor(pos_x, pos_y)) # add the zombies count = self.width * self.height / 100; if terrain == self.terrain_city: count = count * 2 elif terrain == self.terrain_rural: count = count / 2 for ii in range(0, int(count)): pos_x = 0 pos_y = 0 while self.CanMove(None, pos_x, pos_y) == False or self.IsInside(pos_x, pos_y) == True: pos_x = random.randint(0, self.width - 1) pos_y = random.randint(0, self.height - 1) self.actors.append(Zombie(pos_x, pos_y)) # add the items for room in self.rooms: building_description, building_type, room_x, room_y, room_width, room_height = room base_chance = 100 per_chance = 10 base_item_count = 5 max_item_count = 10 armor_chance = building_type[5] weapon_chance = building_type[6] loadable_chance = building_type[7] food_chance = building_type[8] item_chance = (armor_chance + weapon_chance + loadable_chance + food_chance) deco_chance = 5 #print "populating %s, %i chance" % (building_description, item_chance) for yy in range(room_y, room_y + room_height): for xx in range(room_x, room_x + room_width): if self.terrain_board[yy][xx] is None: # empty square, check for items if random.randint(0, base_chance) < item_chance: #print "placing" count = 0 while count == 0: which = random.randint(0, 3) chance = random.randint(0, base_chance) if which == 0 and chance < building_type[5] * per_chance: # armor count = random.randint(0, int(base_item_count * building_type[5])) count = min(count, max_item_count) #print "%i armor" % count for ii in range(0, count): item = self.armors[random.randint(0, len(self.armors) - 1)] self.items.append([xx, yy, Armor(item[0], item[1], item[2])]) elif which == 3 and chance < building_type[6] * per_chance: # weapons count = random.randint(0, int(base_item_count * building_type[6])) count = min(count, max_item_count) #print "%i weapons" % count for ii in range(0, count): item = self.weapons[random.randint(0, len(self.weapons) - 1)] self.items.append([xx, yy, Weapon(item[0], item[1], item[2], item[3], item[4], item[5])]) # loadable weapons elif which == 3 and chance < building_type[7] * per_chance: count = random.randint(0, int(base_item_count * building_type[7])) count = min(count, max_item_count) #print "%i guns" % count for ii in range(0, count): item_pair = self.loadable_weapons[random.randint(0, len(self.loadable_weapons) - 1)] if random.randint(0, 2) == 0: self.items.append([xx, yy, LoadableWeapon(item_pair[0][0], item_pair[0][1], item_pair[0][2], item_pair[0][3], item_pair[0][4], item_pair[0][5], item_pair[0][6])]) else: count -= 1 ammo_count = random.randint(0, 2) for jj in range(0, ammo_count): count += 1 if count > max_item_count: break self.items.append([xx, yy, Ammunition(item_pair[1][0], item_pair[1][1], item_pair[1][2], random.randint(1, item_pair[1][3]))]) elif which == 3 and chance < building_type[8] * per_chance: # food count = random.randint(0, int(base_item_count * building_type[8])) count = min(count, max_item_count) #print "%i food" % count for ii in range(0, count): item = self.foods[random.randint(0, len(self.foods) - 1)] self.items.append([xx, yy, Food(item[0], item[1], item[2], item[3])]) # add storage deco deco = random.randint(0, self.storage_floor_count - 1) self.decorations.append((xx, yy, self.deco_storage_floor, deco)) else: # check for decorations if random.randint(0, base_chance) < deco_chance: deco = random.randint(0, self.deco_floor_count - 1) self.decorations.append((xx, yy, self.deco_floor, deco)) elif isinstance(self.terrain_board[yy][xx], Wall) and not self.terrain_board[yy][xx].HasChildren(): if self.terrain_board[yy][xx].direction == Feature.DIRECTION_EW: # check for decorations if random.randint(0, base_chance) < deco_chance: deco = random.randint(0, self.deco_wall_count - 1) self.decorations.append((xx, yy, self.deco_wall_ew, deco)) elif self.terrain_board[yy][xx].direction == Feature.DIRECTION_NS: # check for decorations if random.randint(0, base_chance) < deco_chance: deco = random.randint(0, self.deco_wall_count - 1) self.decorations.append((xx, yy, self.deco_wall_ns, deco)) def InitializeBoards(self, board_base): for yy in xrange(0, self.height): self.board.append([]) self.terrain_board.append([]) self.overlay_board.append([]) self.object_board.append([]) self.path_board.append([]) self.vis_board.append([]) self.los_board.append([]) for xx in xrange(0, self.width): self.los_board[yy].append(self.los_unseen) self.board[yy].append(board_base) self.terrain_board[yy].append(None) self.overlay_board[yy].append([]) self.object_board[yy].append([]) self.path_board[yy].append(self.path_yes) self.vis_board[yy].append(self.vis_yes) def GenerateCity(self): self.InitializeBoards(self.board_concrete) # add the roads road_width = 5 # split board vertically bisect_x = random.randint(1, self.width - road_width - 1) self.AddRoad(road_width, bisect_x, 0, False, False) # split board horizontally bisect_y = random.randint(1, self.height - road_width - 1) self.AddRoad(road_width, 0, bisect_y, True, False) min_spacing = 8 spacing_counter = 0 # add little roads vertically for xx in xrange(1, self.width - 1): if self.board[0][xx] == self.board_road: spacing_counter = 0 elif spacing_counter > min_spacing and random.randint(0, 5) == 0: spacing_counter = 0 self.AddRoad(random.randint(2, 3), xx, 0, False, False) spacing_counter += 1 # add little roads horizontally for yy in xrange(1, self.height - 1): if self.board[yy][0] == self.board_road: spacing_counter = 0 elif spacing_counter > min_spacing and random.randint(0, 5) == 0: spacing_counter = 0 self.AddRoad(random.randint(2, 3), 0, yy, True, False) spacing_counter += 1 # create some buildings #print "makin' buildin's" for room_count in xrange(0, (self.width * self.height) / 20): self.AddBuilding(self.terrain_city, 3, 3, self.width / 5, self.height / 5) self.MatchTiles() self.Populate(self.terrain_city) def GenerateSuburb(self): self.InitializeBoards(self.board_grass) # add the road road_width = 5 # split board vertically bisect_x = random.randint(1, self.width - road_width - 1) self.AddRoad(road_width, bisect_x, 0, False, True) # split board horizontally bisect_y = random.randint(1, self.height - road_width - 1) self.AddRoad(road_width, 0, bisect_y, True, True) # create some buildings #print "makin' buildin's" for room_count in xrange(0, (self.width * self.height) / 100): self.AddBuilding(self.terrain_suburb) self.MatchTiles() self.Populate(self.terrain_suburb) def GenerateRural(self): self.InitializeBoards(self.board_grass) # create some buildings #print "makin' buildin's" for room_count in xrange(0, (self.width * self.height) / 1000): self.AddBuilding(self.terrain_rural) self.MatchTiles() self.Populate(self.terrain_rural) def BisectRoom(self, room_x, room_y, room_width, room_height): # bisect? #print "bisecting" # 0% chance for 5x5 room, up from there #print "bisect %i,%i,%i,%i" % (room_x,room_y,room_width,room_height) #print "%i bisect chance" % (room_width * room_height) if random.randint(0, room_width * room_height) > 25: # yes, let's weight the height and width to make a long split more likely width_weight = random.randint(0, room_width) height_weight = random.randint(0, room_height) if room_width >= 5 and width_weight > height_weight: #print "vertical" # split wider room vertically bisect_x = random.randint(room_x + 2, room_x + room_width - 2) tries = 0 #while self.terrain_board[room_y][bisect_x] != self.feature_wall or self.terrain_board[room_y + room_height][bisect_x] != self.feature_wall: while self.terrain_board[room_y][bisect_x] is None or not self.terrain_board[room_y][bisect_x].HasChildren() or self.terrain_board[room_y + room_height][bisect_x] is None or not self.terrain_board[room_y + room_height][bisect_x].HasChildren(): tries = tries + 1 if tries > 10: return False #print "fail %i" % bisect_x bisect_x = random.randint(room_x + 2, room_x + room_width - 2) #print "got %i" % bisect_x for yy in xrange(room_y + 1, room_y + room_height): #self.terrain_board[yy][bisect_x] = self.feature_wall self.terrain_board[yy][bisect_x] = Wall() self.path_board[yy][bisect_x] = self.path_no self.vis_board[yy][bisect_x] = self.vis_no door_y = random.randint(room_y + 1, room_y + room_height - 1) self.board[door_y][bisect_x] = self.board_floor if random.randint(0, 1) == 0: # 50% chance of door #self.features.append((bisect_x, door_y, self.feature_door_closed_ns, "Interior Door")) #self.terrain_board[door_y][bisect_x] = self.feature_door_closed_ns #self.terrain_board[door_y][bisect_x] = None #self.features.append(Door("Interior", bisect_x, door_y, Feature.DIRECTION_NS)) self.terrain_board[door_y][bisect_x].AddDoor("Interior") else: self.terrain_board[door_y][bisect_x] = None self.path_board[door_y][bisect_x] = self.path_yes self.vis_board[door_y][bisect_x] = self.vis_yes # bisect left half #print "do left" self.BisectRoom(room_x, room_y, bisect_x - room_x, room_height) # bisect right half #print "do right" self.BisectRoom(bisect_x, room_y, room_width - (bisect_x - room_x), room_height) elif room_height >= 5 and height_weight > width_weight: #print "horizontal" # split taller room horizontally bisect_y = random.randint(room_y + 2, room_y + room_height - 2) tries = 0 #while self.terrain_board[bisect_y][room_x] != self.feature_wall or self.terrain_board[bisect_y][room_x + room_width] != self.feature_wall: while self.terrain_board[bisect_y][room_x] is None or not self.terrain_board[bisect_y][room_x].HasChildren() or self.terrain_board[bisect_y][room_x + room_width] is None or not self.terrain_board[bisect_y][room_x + room_width].HasChildren(): tries = tries + 1 if tries > 10: return False #print "fail %i" % bisect_y bisect_y = random.randint(room_y + 2, room_y + room_height - 2) #print "got %i" % bisect_y for xx in xrange(room_x + 1, room_x + room_width): #self.terrain_board[bisect_y][xx] = self.feature_wall self.terrain_board[bisect_y][xx] = Wall() self.path_board[bisect_y][xx] = self.path_no self.vis_board[bisect_y][xx] = self.vis_no door_x = random.randint(room_x + 1, room_x + room_width - 1) self.board[bisect_y][door_x] = self.board_floor if random.randint(0, 1) == 0: # 50% chance of door #self.features.append((door_x, bisect_y, self.feature_door_closed_ew, "Interior Door")) #self.terrain_board[bisect_y][door_x] = self.feature_door_closed_ew #self.terrain_board[bisect_y][door_x] = None #self.features.append(Door("Interior", door_x, bisect_y, Feature.DIRECTION_EW)) self.terrain_board[bisect_y][door_x].AddDoor("Interior") else: self.terrain_board[bisect_y][door_x] = None self.path_board[bisect_y][door_x] = self.path_yes self.vis_board[bisect_y][door_x] = self.vis_yes # bisect top half #print "do top" self.BisectRoom(room_x, room_y, room_width, bisect_y - room_y) # bisect bottom half #print "do bottom" self.BisectRoom(room_x, bisect_y, room_width, room_height - (bisect_y - room_y)) # no else means equal will just not split def GetOffsets(self, view_width, view_height, player): view_width_tiles = math.ceil(view_width / self.tile_width) view_height_tiles = math.ceil(view_height / self.tile_height) half_view_width_tiles = math.floor(view_width_tiles / 2) half_view_height_tiles = math.floor(view_height_tiles / 2) offset_x_tiles = player.pos_x - half_view_height_tiles offset_y_tiles = player.pos_y - half_view_height_tiles """ if offset_x_tiles < 0: #player is near the beginning of the screen offset_x_tiles = 0 elif offset_x_tiles > self.width - view_width_tiles: #player is near the end of the screen offset_x_tiles = self.width - view_width_tiles if offset_y_tiles < 0: #player is near the beginning of the screen offset_y_tiles = 0 elif offset_y_tiles > self.height - view_height_tiles: #player is near the end of the screen offset_y_tiles = self.height - view_height_tiles """ offset_x = offset_x_tiles * self.tile_width / 2 offset_y = offset_y_tiles * self.tile_height """ offset_x = (player.pos_x * self.tile_width / 2) - (view_width / 2) offset_y = (player.pos_y * self.tile_height) - (view_height / 2) """ return offset_x, offset_y def GetTileAt(self, view_width, view_height, player, pos): offset_x, offset_y = self.GetOffsets(view_width, view_height, player) origin_x = view_width / 2 origin_y = 0#self.tile_height # First we need to get the x and y coordinates of the screen position relative to the scroll and centre coordinates: x0 = float(pos[0] - origin_x) y0 = float(pos[1] - origin_y) # add the offsets back to get a true raw value x0 += (offset_x - offset_y) y0 += (offset_y + offset_x) / 2 # From these values we can start to calculate the Map coordinates: x = y0 + (x0 / 2.) y = y0 - (x0 / 2.) # These are the map coordinates multiplied by the TileDepth grid size, # so we'll divide both of these X and Y values by TileDepth to get the actual Map coordinates tile_x = int(x / float(self.tile_height)) tile_y = int(y / float(self.tile_height)) return tile_x, tile_y def GetPositionForTile(self, pos_x, pos_y, origin_x, origin_y, offset_x = 0, offset_y = 0): # get the raw pixel location half_width = float(self.tile_width) / 2. half_height = float(self.tile_height) / 2. # multiply the y by half the width, to get the southwest shift shift_x_height = pos_y * half_width # multiply the x by half the width, to get the southeast shift shift_x_width = pos_x * half_width # multiply the y by half the height, to increase the southwest shift shift_y_height = pos_y * half_height # multyply the x by half the height, to increase the southeast shift shift_y_width = pos_x * half_height draw_x = origin_x - shift_x_height + shift_x_width draw_y = origin_y + shift_y_height + shift_y_width # subtract the offsets to track the screen draw_x -= (offset_x - offset_y) draw_y -= (offset_y + offset_x) / 2 return draw_x, draw_y def Draw(self, view_width, view_height, mini_map, player, crosshair_pos): board_tiles = pygame.sprite.OrderedUpdates() fog_tiles = pygame.sprite.OrderedUpdates() offset_x, offset_y = self.GetOffsets(view_width, view_height, player) origin_x = view_width / 2 - (self.tile_width / 2) origin_y = -self.tile_height#0 #print offset_x, offset_y #sys.exit() # loop through entire board and decide to draw or not # could later be optimized to loop only through drawable area for yy in xrange(len(self.board)): for xx in xrange(len(self.board[yy])): if self.los_board[yy][xx] != self.los_unseen: # draw the mini map mini_map_color = (0,0,0) if self.terrain_board[yy][xx] is not None: if self.los_board[yy][xx] == self.los_seen: mini_map_color = (155,155,155) elif self.los_board[yy][xx] == self.los_visible: mini_map_color = (255,255,255) else: if (self.board[yy][xx] == self.board_floor or self.board[yy][xx] == self.board_grass_floor_e or self.board[yy][xx] == self.board_grass_floor_n or self.board[yy][xx] == self.board_grass_floor_ne or self.board[yy][xx] == self.board_grass_floor_nw or self.board[yy][xx] == self.board_grass_floor_s or self.board[yy][xx] == self.board_grass_floor_se or self.board[yy][xx] == self.board_grass_floor_sw or self.board[yy][xx] == self.board_grass_floor_w): if self.los_board[yy][xx] == self.los_seen: mini_map_color = (10,10,10) elif self.los_board[yy][xx] == self.los_visible: mini_map_color = (25,25,25) elif self.board[yy][xx] == self.board_grass: if self.los_board[yy][xx] == self.los_seen: mini_map_color = (0,10,0) elif self.los_board[yy][xx] == self.los_visible: mini_map_color = (10,25,10) elif self.board[yy][xx] == self.board_road: if self.los_board[yy][xx] == self.los_seen: mini_map_color = (10,10,0) elif self.los_board[yy][xx] == self.los_visible: mini_map_color = (25,25,10) elif self.board[yy][xx] == self.board_concrete: if self.los_board[yy][xx] == self.los_seen: mini_map_color = (10,10,10) elif self.los_board[yy][xx] == self.los_visible: mini_map_color = (25,25,25) pygame.draw.line(mini_map, mini_map_color, (xx, yy), (xx, yy)) # draw the tiles #draw_x = self.tile_width * xx - offset_x #draw_y = self.tile_height * yy - offset_y draw_x, draw_y = self.GetPositionForTile(xx, yy, origin_x, origin_y, offset_x, offset_y) if -self.tile_width <= draw_x < view_width and -self.tile_width <= draw_y < view_height: # it's in the view port tile = Sprite() if (self.board[yy][xx] == self.board_floor): tile.image = self.image_floor elif (self.board[yy][xx] == self.board_grass_floor_e): tile.image = self.image_grass_floor_e elif (self.board[yy][xx] == self.board_grass_floor_n): tile.image = self.image_grass_floor_n elif (self.board[yy][xx] == self.board_grass_floor_ne): tile.image = self.image_grass_floor_ne elif (self.board[yy][xx] == self.board_grass_floor_nw): tile.image = self.image_grass_floor_nw elif (self.board[yy][xx] == self.board_grass_floor_s): tile.image = self.image_grass_floor_s elif (self.board[yy][xx] == self.board_grass_floor_se): tile.image = self.image_grass_floor_se elif (self.board[yy][xx] == self.board_grass_floor_sw): tile.image = self.image_grass_floor_sw elif (self.board[yy][xx] == self.board_grass_floor_w): tile.image = self.image_grass_floor_w elif (self.board[yy][xx] == self.board_grass): tile.image = self.image_grass elif (self.board[yy][xx] == self.board_road): tile.image = self.image_road elif (self.board[yy][xx] == self.board_concrete): tile.image = self.image_concrete tile.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) if self.los_board[yy][xx] == self.los_visible: board_tiles.add(tile) else: fog_tiles.add(tile) # draw terrain if self.terrain_board[yy][xx] is not None: """ if self.terrain_board[yy][xx] == self.feature_wall: tile.image = self.image_wall elif self.terrain_board[yy][xx] == self.feature_wall_e: tile.image = self.image_wall_e elif self.terrain_board[yy][xx] == self.feature_wall_es: tile.image = self.image_wall_es elif self.terrain_board[yy][xx] == self.feature_wall_esw: tile.image = self.image_wall_esw elif self.terrain_board[yy][xx] == self.feature_wall_ew: tile.image = self.image_wall_ew elif self.terrain_board[yy][xx] == self.feature_wall_n: tile.image = self.image_wall_n elif self.terrain_board[yy][xx] == self.feature_wall_ne: tile.image = self.image_wall_ne elif self.terrain_board[yy][xx] == self.feature_wall_nes: tile.image = self.image_wall_nes elif self.terrain_board[yy][xx] == self.feature_wall_nesw: tile.image = self.image_wall_nesw elif self.terrain_board[yy][xx] == self.feature_wall_new: tile.image = self.image_wall_new elif self.terrain_board[yy][xx] == self.feature_wall_ns: tile.image = self.image_wall_ns elif self.terrain_board[yy][xx] == self.feature_wall_nsw: tile.image = self.image_wall_nsw elif self.terrain_board[yy][xx] == self.feature_wall_nw: tile.image = self.image_wall_nw elif self.terrain_board[yy][xx] == self.feature_wall_s: tile.image = self.image_wall_s elif self.terrain_board[yy][xx] == self.feature_wall_sw: tile.image = self.image_wall_sw elif self.terrain_board[yy][xx] == self.feature_wall_w: tile.image = self.image_wall_w """ if self.terrain_board[yy][xx].image is not None: tile = Sprite() tile.image = self.terrain_board[yy][xx].image tile.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) if self.los_board[yy][xx] == self.los_visible: board_tiles.add(tile) else: fog_tiles.add(tile) #if not self.terrain_board[yy][xx].HasChildren() and self.terrain_board[yy][xx].child_feature.image is not None: for feature in self.terrain_board[yy][xx].children: if feature.image is not None: tile = Sprite() tile.image = feature.image tile.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) if self.los_board[yy][xx] == self.los_visible: board_tiles.add(tile) else: fog_tiles.add(tile) #if self.los_board[yy][xx] == self.los_seen: # # draw fog # tile = Sprite() # tile.image = self.image_fog # tile.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) # board_tiles.add(tile) for deco in self.decorations: if deco[0] == xx and deco[1] == yy: item_sprite = Sprite() if deco[2] == self.deco_floor: item_sprite.image = self.images_deco_floor[deco[3]] elif deco[2] == self.deco_grass: item_sprite.image = self.images_deco_grass[deco[3]] elif deco[2] == self.deco_wall_ew: item_sprite.image = self.images_deco_wall_ew[deco[3]] elif deco[2] == self.deco_wall_ns: item_sprite.image = self.images_deco_wall_ns[deco[3]] elif deco[2] == self.deco_block_floor: item_sprite.image = self.images_block_floor[deco[3]] elif deco[2] == self.deco_block_grass: item_sprite.image = self.images_block_grass[deco[3]] elif deco[2] == self.deco_obj_floor: item_sprite.image = self.images_obj_floor[deco[3]] elif deco[2] == self.deco_obj_grass: item_sprite.image = self.images_obj_grass[deco[3]] elif deco[2] == self.deco_storage_floor: item_sprite.image = self.images_storage_floor[deco[3]] item_sprite.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) if self.los_board[yy][xx] == self.los_visible: board_tiles.add(item_sprite) else: fog_tiles.add(item_sprite) for item in self.items: #if self.los_board[item[1]][item[0]] == self.los_visible: if item[0] == xx and item[1] == yy and self.los_board[yy][xx] == self.los_visible: #draw_x, draw_y = self.GetPositionForTile(item[0], item[1], origin_x, origin_y, offset_x, offset_y) #if 0 <= draw_x < view_width and 0 <= draw_y < view_height: item_sprite = Sprite() item_sprite.image = item[2].image item_sprite.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) board_tiles.add(item_sprite) item_color = (255,255,0) pygame.draw.line(mini_map, item_color, (item[0], item[1]), (item[0], item[1])) """ for feature in self.features: #if self.los_board[feature[1]][feature[0]] == self.los_visible: if feature.pos_x == xx and feature.pos_y == yy: #draw_x, draw_y = self.GetPositionForTile(feature[0], feature[1], origin_x, origin_y, offset_x, offset_y) feature_sprite = Sprite() feature_sprite.image = feature.image #if 0 <= draw_x < view_width and 0 <= draw_y < view_height: feature_sprite.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) if self.los_board[yy][xx] == self.los_visible: board_tiles.add(feature_sprite) else: fog_tiles.add(feature_sprite) pygame.draw.line(mini_map, feature.color, (feature.pos_x, feature.pos_y), (feature.pos_x, feature.pos_y)) """ for actor in self.actors: #if self.los_board[actor.pos_y][actor.pos_x] == self.los_visible: if actor.pos_x == xx and actor.pos_y == yy and self.los_board[yy][xx] == self.los_visible: #draw_x, draw_y = self.GetPositionForTile(actor.pos_x, actor.pos_y, origin_x, origin_y, offset_x, offset_y) #if 0 <= draw_x < view_width and 0 <= draw_y < view_height: sprite = Sprite() sprite.image = actor.image sprite.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) #board_tiles.add(actor.sprite) sprite.add(board_tiles) if isinstance(actor, Zombie): actor_color = (0,255,0) elif isinstance(actor, Player): actor_color = (255,0,0) elif isinstance(actor, Human): actor_color = (0,0,255) else: actor_color = (255,255,255) pygame.draw.line(mini_map, actor_color, (actor.pos_x, actor.pos_y), (actor.pos_x, actor.pos_y)) for barricade in self.barricades: #if self.los_board[barricade[1]][barricade[0]] != self.los_unseen: if barricade[0] == xx and barricade[1] == yy: #draw_x, draw_y = self.GetPositionForTile(barricade[0], barricade[1], origin_x, origin_y, offset_x, offset_y) color = (0,0,0) #if 0 <= draw_x < view_width and 0 <= draw_y < view_height: sprite = Sprite() sprite.image = self.image_barricades[barricade[2]] color = (255,0,0) sprite.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) if self.los_board[yy][xx] == self.los_visible: board_tiles.add(sprite) pygame.draw.line(mini_map, color, (barricade[0], barricade[1]), (barricade[0], barricade[1])) if crosshair_pos is not None and crosshair_pos[0] == xx and crosshair_pos[1] == yy: #draw_x, draw_y = self.GetPositionForTile(crosshair_pos[0], crosshair_pos[1], offset_x, offset_y) sprite = Sprite() sprite.image = self.image_crosshair sprite.rect = pygame.Rect(draw_x, draw_y, self.tile_width, self.tile_height) board_tiles.add(sprite) return board_tiles, fog_tiles, mini_map def CanMove(self, target_actor, dest_x, dest_y): #if 0 > dest_x >= self.width or 0 > dest_y >= self.height: if dest_x < 0 or dest_x >= self.width or dest_y < 0 or dest_y >= self.height: return False #print (dest_x, dest_y, self.width, self.height) if self.path_board[dest_y][dest_x] == self.path_yes: for actor in self.actors: if actor.pos_x == dest_x and actor.pos_y == dest_y: return False return True else: return False def TryOpen(self, dest_x, dest_y): opened = False # if self.terrain_board[dest_y][dest_x] == self.feature_door_closed_ns or self.terrain_board[dest_y][dest_x] == self.feature_door_closed_ew: #for feature in self.features: # if feature.pos_x == dest_x and feature.pos_y == dest_y and isinstance(feature, Door): if 0 < dest_x <= self.width and 0 < dest_y <= self.height: #if isinstance(self.terrain_board[dest_y][dest_x], OpenableFeature) and self.terrain_board[dest_y][dest_x].is_open == False: """ barricaded = False for barricade in self.barricades: if barricade[0] == dest_x and barricade[1] == dest_y: barricaded = True break if not barricaded: if self.terrain_board[dest_y][dest_x] == self.feature_door_closed_ns: #self.features.append((feature[0], feature[1], self.feature_door_open_ns, feature[3])) self.terrain_board[dest_y][dest_x] = self.feature_door_open_ns elif self.terrain_board[dest_y][dest_x] == self.feature_door_closed_ew: self.terrain_board[dest_y][dest_x] = self.feature_door_open_ew #self.features.append((feature[0], feature[1], self.feature_door_open_ew, feature[3])) #self.features.remove(feature) """ #if self.terrain_board[dest_y][dest_x] is not None and isinstance(self.terrain_board[dest_y][dest_x].child_feature, OpenableFeature) and self.terrain_board[dest_y][dest_x].child_feature.is_open == False: if self.terrain_board[dest_y][dest_x] is not None: if isinstance(self.terrain_board[dest_y][dest_x], OpenableFeature) and not self.terrain_board[dest_y][dest_x].is_open: self.terrain_board[dest_y][dest_x].Open() self.path_board[dest_y][dest_x] = self.path_yes self.vis_board[dest_y][dest_x] = self.vis_yes opened = True for feature in self.terrain_board[dest_y][dest_x].children: if isinstance(feature, OpenableFeature) and not feature.is_open: feature.Open() self.path_board[dest_y][dest_x] = self.path_yes self.vis_board[dest_y][dest_x] = self.vis_yes opened = True return opened def TryClose(self, dest_x, dest_y): closed = False #for feature in self.features: # if feature.pos_x == dest_x and feature.pos_y == dest_y and is_instance(feature, Door): if self.terrain_board[dest_y][dest_x] is not None: if isinstance(self.terrain_board[dest_y][dest_x], OpenableFeature) and self.terrain_board[dest_y][dest_x].is_open: self.terrain_board[dest_y][dest_x].Close() self.path_board[dest_y][dest_x] = self.path_no self.vis_board[dest_y][dest_x] = self.vis_no opened = True for feature in self.terrain_board[dest_y][dest_x].children: if isinstance(feature, OpenableFeature) and feature.is_open: feature.Close() self.path_board[dest_y][dest_x] = self.path_no self.vis_board[dest_y][dest_x] = self.vis_no opened = True """ if 0 < dest_x <= self.width and 0 < dest_y <= self.height: if self.terrain_board[dest_y][dest_x] == self.feature_door_open_ns: #self.features.append((feature[0], feature[1], self.feature_door_closed_ns, feature[3])) #self.features.remove(feature) self.terrain_board[dest_y][dest_x] = self.feature_door_closed_ns self.path_board[dest_y][dest_x] = self.path_no self.vis_board[dest_y][dest_x] = self.vis_no closed = True elif self.terrain_board[dest_y][dest_x] == self.feature_door_open_ew: #self.features.append((feature[0], feature[1], self.feature_door_closed_ew, feature[3])) #self.features.remove(feature) self.terrain_board[dest_y][dest_x] = self.feature_door_closed_ew self.path_board[dest_y][dest_x] = self.path_no self.vis_board[dest_y][dest_x] = self.vis_no closed = True """ return closed def TryBarricade(self, dest_x, dest_y): barricaded = False """ for feature in self.features: if feature[0] == dest_x and feature[1] == dest_y: if feature[2] == self.feature_door_closed_ns or feature[2] == self.feature_door_closed_ew or feature[2] == self.feature_window_ns or feature[2] == self.feature_window_ew: already_barricaded = False for barricade in self.barricades: if barricade[0] == dest_x and barricade[1] == dest_y: already_barricaded = True if barricade[2] < 3: barricade[2] += 1 barricaded = True if not already_barricaded: self.barricades.append([dest_x, dest_y, 0]) barricaded = True break """ return barricaded def TryUnbarricade(self, dest_x, dest_y): unbarricaded = False for barricade in self.barricades: if barricade[0] == dest_x and barricade[1] == dest_y: unbarricaded = True self.Unbarricade(barricade) break return unbarricaded def Unbarricade(self, barricade): barricade[2] -= 1 if barricade[2] < 0: self.barricades.remove(barricade) def IsVisible(self, dest_x, dest_y): return self.los_board[dest_y][dest_x] == self.los_visible def IsInside(self, dest_x, dest_y): return self.board[dest_y][dest_x] == self.board_floor def CalculateLineOfSight(self, player): # clear the board for yy in xrange(len(self.board)): for xx in xrange(len(self.board[yy])): if self.los_board[yy][xx] == self.los_visible: self.los_board[yy][xx] = self.los_seen done = False start_x = max(0, player.pos_x - player.GetVisibility()) stop_x = min(self.width - 1, player.pos_x + player.GetVisibility() - 1) start_y = max(0, player.pos_y - player.GetVisibility()) stop_y = min(self.height - 1, player.pos_y + player.GetVisibility() - 1) while not done: xx = start_x yy = start_y step_x = 1 step_y = 0 found_blocked = False #print (start_x, start_y, stop_x, stop_y) while not done: # check this square if los not yet found #print ("Running", xx, yy) if self.los_board[yy][xx] != self.los_visible: line, found = get_bresen(self.vis_board, player.pos_x, player.pos_y, xx, yy) for point in line: dist = ((player.pos_x - point[0]) ** 2) + ((player.pos_y - point[1]) ** 2) vis = player.GetVisibility() ** 2 # if in range if dist < vis: #print ("Opening", point[0], point[1]) self.los_board[point[1]][point[0]] = self.los_visible else: #print ("Nope", point[0], point[1]) found_blocked = True if not found: found_blocked = True """ line, found = get_bresen(self.vis_board, xx, yy, player.pos_x, player.pos_y) if found: for point in line: dist = ((player.pos_x - point[0]) ** 2) + ((player.pos_y - point[1]) ** 2) vis = player.GetVisibility() ** 2 # if in range if dist < vis: #print ("Opening", point[0], point[1]) self.los_board[point[1]][point[0]] = self.los_visible else: #print ("Nope", point[0], point[1]) found_blocked = True else: found_blocked = True """ xx += step_x yy += step_y if step_x == 1 and xx == stop_x: # we were going right and we hit the end step_x = 0 step_y = 1 elif step_y == 1 and yy == stop_y: # we were going down and we hit the end step_y = 0 step_x = -1 elif step_x == -1 and xx == start_x: # we were going left and we hit the start step_x = 0 step_y = -1 elif step_y == -1 and yy == start_y: # we were going up and we hit the start step_y = 0 step_x = 1 done = True # done with one loop, but check the next if there were any blocked areas if found_blocked: #print "blocked, again" start_x += 1 start_y += 1 stop_x -= 1 stop_y -= 1 if stop_x > start_x and stop_y > start_y: done = False #else: # print "no block, stop" def GetTargetsAt(self, view_width, view_height, player, pos): targets = [] tile_x, tile_y = self.GetTileAt(view_width, view_height, player, pos) if 0 <= tile_x < self.width and 0 <= tile_y < self.height: #targets.append("%i %i" % (tile_x, tile_y)) if self.los_board[tile_y][tile_x] == self.los_visible:# or self.los_board[tile_y][tile_x] == self.los_seen: if self.terrain_board[tile_y][tile_x] is not None: if self.terrain_board[tile_y][tile_x].GetName() is not None: targets.append(self.terrain_board[tile_y][tile_x].GetName()) #if self.terrain_board[tile_y][tile_x].child_feature is not None: # targets.append(self.terrain_board[tile_y][tile_x].child_feature.GetName()) for feature in self.terrain_board[tile_y][tile_x].children: if feature.GetName() is not None: targets.append(feature.GetName()) """ for feature in self.features: if feature.pos_x == tile_x and feature.pos_y == tile_y: targets.append(feature.GetName()) """ for barricade in self.barricades: if barricade[0] == tile_x and barricade[1] == tile_y: targets.append("Barricade x%i" % (barricade[2] + 1)) for actor in self.actors: if actor.pos_x == tile_x and actor.pos_y == tile_y: targets.append(actor.GetName()) for item in self.items: if item[0] == tile_x and item[1] == tile_y: targets.append(item[2].GetName()) return targets def LoadImages(self): self.image_wall = load_image("wall.png", -1) self.image_floor = load_image("floor.png", -1) self.image_grass = load_image("grass.png", -1) self.image_road = load_image("road.png", -1) self.image_concrete = load_image("concrete.png", -1) self.image_grass_floor_e = load_image("grass_floor_e.png", -1) self.image_grass_floor_n = load_image("grass_floor_n.png", -1) self.image_grass_floor_ne = load_image("grass_floor_ne.png", -1) self.image_grass_floor_nw = load_image("grass_floor_nw.png", -1) self.image_grass_floor_s = load_image("grass_floor_s.png", -1) self.image_grass_floor_se = load_image("grass_floor_se.png", -1) self.image_grass_floor_sw = load_image("grass_floor_sw.png", -1) self.image_grass_floor_w = load_image("grass_floor_w.png", -1) self.image_fog = load_image("fog.png", -1) self.image_door = load_image("door.png") self.image_door_open = load_image("door_open.png", (0,0,0)) self.image_window = load_image("window.png") self.image_barricades = [load_image("barricade_1.png", -1), load_image("barricade_2.png", -1), load_image("barricade_3.png", -1), load_image("barricade_4.png", -1)] self.image_crosshair = load_image("crosshair.png", -1) self.image_blood = load_image("blood.png", -1) self.image_wall = load_image("wall_e.png", -1) self.image_wall_e = load_image("wall_e.png", -1) self.image_wall_es = load_image("wall_es.png", -1) self.image_wall_esw = load_image("wall_esw.png", -1) self.image_wall_ew = load_image("wall_ew.png", -1) self.image_wall_n = load_image("wall_n.png", -1) self.image_wall_ne = load_image("wall_ne.png", -1) self.image_wall_nes = load_image("wall_nes.png", -1) self.image_wall_nesw = load_image("wall_nesw.png", -1) self.image_wall_new = load_image("wall_new.png", -1) self.image_wall_ns = load_image("wall_ns.png", -1) self.image_wall_nsw = load_image("wall_nsw.png", -1) self.image_wall_nw = load_image("wall_nw.png", -1) self.image_wall_s = load_image("wall_s.png", -1) self.image_wall_sw = load_image("wall_sw.png", -1) self.image_wall_w = load_image("wall_w.png", -1) self.images_deco_floor = [] for ii in xrange(1, self.deco_floor_count + 1): self.images_deco_floor.append(load_image("deco_floor_%02i.png" % ii, -1)) self.images_deco_grass = [] for ii in xrange(1, self.deco_grass_count + 1): self.images_deco_grass.append(load_image("deco_grass_%02i.png" % ii, -1)) self.images_deco_wall_ew = [] self.images_deco_wall_ns = [] for ii in xrange(1, self.deco_wall_count + 1): self.images_deco_wall_ew.append(load_image("deco_wall_%02i_ew.png" % ii, -1)) self.images_deco_wall_ns.append(load_image("deco_wall_%02i_ns.png" % ii, -1)) self.images_block_grass = [] for ii in xrange(1, self.block_grass_count + 1): self.images_block_grass.append(load_image("block_grass_%02i.png" % ii, -1)) self.images_obj_floor = [] for ii in xrange(1, self.obj_floor_count + 1): self.images_obj_floor.append(load_image("obj_floor_%02i.png" % ii, -1)) self.images_obj_grass = [] for ii in xrange(1, self.obj_grass_count + 1): self.images_obj_grass.append(load_image("obj_grass_%02i.png" % ii, -1)) self.images_storage_floor = [] for ii in xrange(1, self.storage_floor_count + 1): self.images_storage_floor.append(load_image("storage_floor_%02i.png" % ii, -1)) def NukeImages(self): self.image_wall = None self.image_floor = None self.image_grass = None self.image_road = None self.image_concrete = None self.image_grass_floor_e = None self.image_grass_floor_n = None self.image_grass_floor_ne = None self.image_grass_floor_nw = None self.image_grass_floor_s = None self.image_grass_floor_se = None self.image_grass_floor_sw = None self.image_grass_floor_w = None self.image_fog = None self.image_door = None self.image_door_open = None self.image_window = None self.image_barricades = None self.image_crosshair = None self.image_blood = None self.image_wall = None self.image_wall_e = None self.image_wall_es = None self.image_wall_esw = None self.image_wall_ew = None self.image_wall_n = None self.image_wall_ne = None self.image_wall_nes = None self.image_wall_nesw = None self.image_wall_new = None self.image_wall_ns = None self.image_wall_nsw = None self.image_wall_nw = None self.image_wall_s = None self.image_wall_sw = None self.image_wall_w = None self.images_deco_floor = None self.images_deco_grass = None self.images_deco_wall_ew = None self.images_deco_wall_ns = None self.images_block_grass = None self.images_obj_floor = None self.images_obj_grass = None self.images_storage_floor = None def __getstate__(self): self.NukeImages() return self.__dict__ def __setstate__(self, state): self.__dict__.update(state) self.LoadImages() #class Room(object): # def __init__(pos_x, pos_y, width, height, room_type):