# HG changeset patch # User Neil Muller # Date 1258060461 0 # Node ID 2d0ff46118e28e0afa9f6146c8006da78238e55c # Parent ad77b3b71b0865b4f95e01c22f217105ee3fa01b Basic support for z coordinate diff -r ad77b3b71b08 -r 2d0ff46118e2 gamelib/animal.py --- a/gamelib/animal.py Thu Nov 12 15:19:12 2009 +0000 +++ b/gamelib/animal.py Thu Nov 12 21:14:21 2009 +0000 @@ -26,17 +26,17 @@ self.image_left = image_left.copy() self._image_right = image_right self.image_right = image_right.copy() - if hasattr(tile_pos, 'to_tuple'): + if hasattr(tile_pos, 'to_tile_tuple'): self.pos = tile_pos else: - self.pos = Position(tile_pos[0], tile_pos[1]) + self.pos = Position(tile_pos[0], tile_pos[1], 0) self.equipment = [] self.accoutrements = [] self.abode = None self.facing = 'left' def loop(self, tv, _sprite): - ppos = tv.tile_to_view(self.pos.to_tuple()) + ppos = tv.tile_to_view(self.pos.to_tile_tuple()) self.rect.x = ppos[0] self.rect.y = ppos[1] @@ -45,7 +45,7 @@ if hasattr(self, 'DEATH_SOUND'): sound.play_sound(self.DEATH_SOUND) if hasattr(self, 'DEATH_ANIMATION'): - self.DEATH_ANIMATION(gameboard.tv, self.pos.to_tuple()) + self.DEATH_ANIMATION(gameboard.tv, self.pos.to_tile_tuple()) self._game_death(gameboard) def _game_death(self, gameboard): @@ -274,7 +274,7 @@ def _cost_tile(self, pos, gameboard): if gameboard.in_bounds(pos): - this_tile = gameboard.tv.get(pos.to_tuple()) + this_tile = gameboard.tv.get(pos.to_tile_tuple()) cost = self.costs.get(tiles.TILE_MAP[this_tile], 100) else: cost = 100 # Out of bounds is expensive @@ -294,8 +294,8 @@ abs(start_pos.y - final_pos.y) < 2: # pgu gets this case wrong on occasion. return [final_pos] - start = start_pos.to_tuple() - end = final_pos.to_tuple() + start = start_pos.to_tile_tuple() + end = final_pos.to_tile_tuple() points = getline(start, end) points.remove(start) # exclude start_pos if end not in points: @@ -307,6 +307,9 @@ """Find the cheapest path to final_pos, and return the next step along the path.""" # We calculate the cost of the direct path + if final_pos.z < self.pos.z: + # We need to try heading down. + return Position(self.pos.x, self.pos.y, self.pos.z - 1) direct_path = self._gen_path(self.pos, final_pos) min_cost = self._cost_path(direct_path, gameboard) min_path = direct_path @@ -364,6 +367,13 @@ # Caught a chicken self._catch_chicken(self.closest, gameboard) return self.pos + if self.closest.pos.to_tile_tuple() == self.pos.to_tile_tuple(): + # Only differ in z, so next step is in z + if self.closest.pos.z < self.pos.z: + new_z = self.pos.z - 1 + else: + new_z = self.pos.z + 1 + return Position(self.pos.x, self.pos.y, new_z) return self._find_best_path_step(self.closest.pos, gameboard) def _catch_chicken(self, chicken, gameboard): @@ -379,11 +389,17 @@ # We're not moving, so we can skip all the checks return new_pos final_pos = new_pos - blocked = final_pos in self.last_steps - moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2) - for y in range(self.pos.y-1, self.pos.y + 2) - if Position(x,y) != self.pos and \ - Position(x, y) not in self.last_steps] + blocked = False # We don't worry about loops on ladders + if new_pos.z != self.pos.z: + # We can only move up and down a ladder + moves = [Position(self.pos.x, self.pos.y, z) for z + in range(self.pos.z-1, self.pos.z + 2) if z >= 0] + else: + blocked = final_pos in self.last_steps + moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2) + for y in range(self.pos.y-1, self.pos.y + 2) + if Position(x,y) != self.pos and + Position(x, y) not in self.last_steps and self.pos.z == 0] for fox in gameboard.foxes: if fox is not self and fox.pos == final_pos: blocked = True @@ -405,7 +421,7 @@ # No good choice, so stay put return self.pos if gameboard.in_bounds(final_pos): - this_tile = gameboard.tv.get(final_pos.to_tuple()) + this_tile = gameboard.tv.get(final_pos.to_tile_tuple()) else: this_tile = tiles.REVERSE_TILE_MAP['woodland'] if tiles.TILE_MAP[this_tile] == 'broken fence' and self.hunting: @@ -426,7 +442,7 @@ def _make_hole(self, gameboard): """Make a hole in the fence""" - fence = gameboard.get_building(self.dig_pos.to_tuple()) + fence = gameboard.get_building(self.dig_pos.to_tile_tuple()) # Another fox could have made the same hole this turn if fence: fence.damage(gameboard.tv) @@ -442,7 +458,7 @@ # Check the another fox hasn't dug a hole for us # We're too busy digging to notice if a hole appears nearby, # but we'll notice if the fence we're digging vanishes - this_tile = gameboard.tv.get(self.dig_pos.to_tuple()) + this_tile = gameboard.tv.get(self.dig_pos.to_tile_tuple()) if tiles.TILE_MAP[this_tile] == 'broken fence': self.tick = 0 return @@ -480,7 +496,7 @@ """Setup dig parameters, to be overridden if needed""" self.tick = 0 # Costs us nothing to go through a fence. self.dig_pos = dig_pos - self.DIG_ANIMATION(gameboard.tv, dig_pos.to_tuple()) + self.DIG_ANIMATION(gameboard.tv, dig_pos.to_tile_tuple()) self._make_hole(gameboard) class GreedyFox(Fox): @@ -513,7 +529,7 @@ def _make_hole(self, gameboard): """The Rinkhals eats fences""" - fence = gameboard.get_building(self.dig_pos.to_tuple()) + fence = gameboard.get_building(self.dig_pos.to_tile_tuple()) if fence: fence.remove(gameboard.tv) gameboard.remove_building(fence) diff -r ad77b3b71b08 -r 2d0ff46118e2 gamelib/animations.py --- a/gamelib/animations.py Thu Nov 12 15:19:12 2009 +0000 +++ b/gamelib/animations.py Thu Nov 12 21:14:21 2009 +0000 @@ -33,9 +33,9 @@ class WeaponAnimation(Animation): def __init__(self, tv, wielder, layer='animations'): if wielder.facing == 'right': - Animation.__init__(self, tv, wielder.pos.to_tuple(), self.SEQUENCE_RIGHT, layer=layer) + Animation.__init__(self, tv, wielder.pos.to_tile_tuple(), self.SEQUENCE_RIGHT, layer=layer) else: - Animation.__init__(self, tv, wielder.pos.to_tuple(), self.SEQUENCE_LEFT, layer=layer) + Animation.__init__(self, tv, wielder.pos.to_tile_tuple(), self.SEQUENCE_LEFT, layer=layer) class MuzzleFlash(WeaponAnimation): diff -r ad77b3b71b08 -r 2d0ff46118e2 gamelib/buildings.py --- a/gamelib/buildings.py Thu Nov 12 15:19:12 2009 +0000 +++ b/gamelib/buildings.py Thu Nov 12 21:14:21 2009 +0000 @@ -36,7 +36,8 @@ def get_pos(self): bpos = self.building.pos - return (bpos[0] + self.offset[0], bpos[1] + self.offset[1]) + return (bpos[0] + self.offset[0], bpos[1] + self.offset[1], + self.offset[2]) class Floor(object): """A set of places within a building. Places on a @@ -66,6 +67,7 @@ MODIFY_GUN_RANGE = lambda s, x: -1 BREAKABLE = False ABODE = False + FLOORS = None def __init__(self, pos): """Initial image, tile vid position, size and tile number for building.""" @@ -84,12 +86,12 @@ self._floors = [] if self.FLOORS: - for f in range(self.FLOORS): + for f, z in enumerate(self.FLOORS): places = [] for j in range(self.size[1]): row = [] for i in range(self.size[0]): - row.append(Place(self, (i, j))) + row.append(Place(self, (i, j, z))) places.append(row) floor = Floor("Floor %s" % (f+1,), places) self._floors.append(floor) @@ -288,7 +290,7 @@ IMAGE = 'sprites/henhouse.png' SELECTED_IMAGE = 'sprites/select_henhouse.png' NAME = 'Henhouse' - FLOORS = 1 + FLOORS = [0] class DoubleStoryHenHouse(HenHouse): """A double story hen house.""" @@ -300,7 +302,7 @@ IMAGE = 'sprites/hendominium.png' SELECTED_IMAGE = 'sprites/select_hendominium.png' NAME = 'Hendominium' - FLOORS = 2 + FLOORS = [0, 1] class GuardTower(Abode): """A GuardTower.""" @@ -312,7 +314,7 @@ IMAGE = 'sprites/watchtower.png' SELECTED_IMAGE = 'sprites/select_watchtower.png' NAME = 'Watchtower' - FLOORS = 1 + FLOORS = [2] MODIFY_GUN_RANGE = lambda s, x: (3*x)/2 MODIFY_GUN_BASE_HIT = lambda s, x: x-5 @@ -336,7 +338,6 @@ IMAGE_BROKEN = 'tiles/broken_fence.png' SELECTED_IMAGE_BROKEN = 'tiles/broken_fence.png' NAME = 'Fence' - FLOORS = 0 def is_building(obj): diff -r ad77b3b71b08 -r 2d0ff46118e2 gamelib/gameboard.py --- a/gamelib/gameboard.py Thu Nov 12 15:19:12 2009 +0000 +++ b/gamelib/gameboard.py Thu Nov 12 21:14:21 2009 +0000 @@ -776,8 +776,8 @@ for fox in self.foxes.copy(): # Any foxes that didn't make it to the woods are automatically # killed - if self.in_bounds(fox.pos) and self.tv.get(fox.pos.to_tuple()) \ - != self.WOODLAND: + if self.in_bounds(fox.pos) and \ + self.tv.get(fox.pos.to_tile_tuple()) != self.WOODLAND: self.kill_fox(fox) else: self.tv.sprites.remove(fox) diff -r ad77b3b71b08 -r 2d0ff46118e2 gamelib/misc.py --- a/gamelib/misc.py Thu Nov 12 15:19:12 2009 +0000 +++ b/gamelib/misc.py Thu Nov 12 21:14:21 2009 +0000 @@ -8,23 +8,24 @@ class Position(object): """2D position / vector""" - def __init__(self, x, y): + def __init__(self, x, y, z=0): self.x = x self.y = y + self.z = z - def to_tuple(self): + def to_tile_tuple(self): return self.x, self.y def dist(self, b): """Gives the distance to another position""" - return max(abs(self.x - b.x), abs(self.y - b.y)) + return max(abs(self.x - b.x), abs(self.y - b.y), abs(self.z - b.z)) def __sub__(self, b): - return Position(self.x - b.x, self.y - b.y) + return Position(self.x - b.x, self.y - b.y, self.z - b.z) def __add__(self, b): - return Position(self.x + b.x, self.y + b.y) + return Position(self.x + b.x, self.y + b.y, self.z + b.z) def left_of(self, b): return self.x < b.x @@ -33,7 +34,7 @@ return self.x > b.x def __eq__(self, b): - return self.x == b.x and self.y == b.y + return self.x == b.x and self.y == b.y and self.z == b.z class WeightedSelection(object): def __init__(self, weightings=None):