changeset 397:532f1ea476ff

Make foxes enter buildings, with a seperate count for them
author Neil Muller <drnlmuller@gmail.com>
date Fri, 13 Nov 2009 14:14:57 +0000
parents 19e583e5cdc0
children 082b1ea5f98d
files gamelib/animal.py gamelib/buildings.py gamelib/constants.py gamelib/gameboard.py
diffstat 4 files changed, 66 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/animal.py	Thu Nov 12 21:31:52 2009 +0000
+++ b/gamelib/animal.py	Fri Nov 13 14:14:57 2009 +0000
@@ -273,6 +273,12 @@
         self.safe = False
         self.closest = None
         self.last_steps = []
+        # Foxes don't occupy places in the same way chickens do, but they
+        # can still be inside
+        self.building = None
+
+    def outside(self):
+        return self.building is None
 
     def _game_death(self, gameboard):
         gameboard.kill_fox(self)
@@ -469,12 +475,12 @@
                 # but we'll notice if the fence we're digging vanishes
                 this_tile = gameboard.tv.get(self.dig_pos.to_tile_tuple())
                 if tiles.TILE_MAP[this_tile] == 'broken fence':
-                    self.tick = 0 
+                    self.tick = 0
                 return
             else:
                 # We've dug through the fence, so make a hole
                 self._make_hole(gameboard)
-            return 
+            return
         if self.hunting:
             desired_pos = self._find_path_to_chicken(gameboard)
         else:
@@ -482,6 +488,25 @@
         final_pos = self._update_pos(gameboard, desired_pos)
         self._fix_face(final_pos)
         self.pos = final_pos
+        # See if we're entering/leaving a building
+        building = gameboard.get_building(final_pos.to_tile_tuple())
+        if building and self.outside():
+                # Check if we need to enter
+                if self.closest and not self.closest.outside() and \
+                        self.closest.abode.building is building:
+                    building.add_predator(self)
+        elif self.building and final_pos.z == 0:
+            # can only leave from the ground floor
+            if building == self.building:
+                # Check if we need to leave the building
+                if not self.hunting or (self.closest and
+                        self.closest.abode.building is not building):
+                    self.building.remove_predator(self)
+            else:
+                # we've moved away from the building we were in
+                self.building.remove_predator(self)
+        gameboard.set_visibility(self)
+
 
 class NinjaFox(Fox):
     """Ninja foxes are hard to see"""
--- a/gamelib/buildings.py	Thu Nov 12 21:31:52 2009 +0000
+++ b/gamelib/buildings.py	Fri Nov 13 14:14:57 2009 +0000
@@ -20,7 +20,7 @@
         self.building = building
         self.offset = offset
 
-    def set_occupant(self, occupant, _update=True):
+    def set_occupant(self, occupant, _update=True, _predator=False):
         self.clear_occupant(_update=False)
         self.occupant = occupant
         self.occupant.abode = self
@@ -83,6 +83,7 @@
         self._font_image = pygame.Surface(self.images['fixed']['day'].get_size(), flags=SRCALPHA)
         self._font_image.fill((0, 0, 0, 0))
         self._broken = False
+        self._predators = []
 
         self._floors = []
         if self.FLOORS:
@@ -238,16 +239,28 @@
 
     def update_occupant_count(self):
         count = len(list(self.occupants()))
-        if count == 0:
+        if count == 0 and not self._predators:
             if "count" in self.draw_stack:
                 del self.draw_stack["count"]
         else:
+            # Render chicken count
             image = self._font_image.copy()
-            text = self._font.render(str(count), True, constants.FG_COLOR)
             w, h = image.get_size()
-            x, y = text.get_size()
-            image.blit(text, (w - x, h - y))
+            if count:
+                text = self._font.render(str(count), True,
+                        constants.FG_COLOR)
+                # Blit to the right
+                x, y = text.get_size()
+                image.blit(text, (w - x, h - y))
+            # Render predator count
+            if self._predators:
+                text = self._font.render(str(len(self._predators)), True,
+                        constants.PREDATOR_COUNT_COLOR)
+                # Blit to the left
+                x, y = text.get_size()
+                image.blit(text, (0, h - y))
             self.draw_stack["count"] = (1, image)
+
         self._redraw()
 
     def floors(self):
@@ -277,6 +290,17 @@
             if place.occupant is not None:
                 yield place.occupant
 
+    def add_predator(self, animal):
+        animal.building = self
+        self._predators.append(animal)
+        self.update_occupant_count()
+
+    def remove_predator(self, animal):
+        if animal in self._predators:
+            self._predators.remove(animal)
+            animal.building = None
+            self.update_occupant_count()
+
 class Abode(Building):
     ABODE = True
 
--- a/gamelib/constants.py	Thu Nov 12 21:31:52 2009 +0000
+++ b/gamelib/constants.py	Fri Nov 13 14:14:57 2009 +0000
@@ -15,6 +15,7 @@
 
 SCREEN = (800, 600)
 FG_COLOR = (255, 255, 255)
+PREDATOR_COUNT_COLOR = (255, 100, 0) # Approximately fox coloured
 BG_COLOR = (0, 0, 0)
 
 # Mixer constants
--- a/gamelib/gameboard.py	Thu Nov 12 21:31:52 2009 +0000
+++ b/gamelib/gameboard.py	Fri Nov 13 14:14:57 2009 +0000
@@ -527,13 +527,13 @@
             chicken.set_pos(place.get_pos())
         self.set_visibility(chicken)
 
-    def set_visibility(self, chicken):
-        if chicken.outside():
-            if chicken not in self.tv.sprites:
-                self.tv.sprites.append(chicken)
+    def set_visibility(self, animal):
+        if animal.outside():
+            if animal not in self.tv.sprites:
+                self.tv.sprites.append(animal)
         else:
-            if chicken in self.tv.sprites:
-                self.tv.sprites.remove(chicken)
+            if animal in self.tv.sprites:
+                self.tv.sprites.remove(animal)
 
     def open_dialog(self, widget, x=None, y=None, close_callback=None):
         """Open a dialog for the given widget. Add close button."""
@@ -780,7 +780,7 @@
                     self.tv.get(fox.pos.to_tile_tuple()) != self.WOODLAND:
                 self.kill_fox(fox)
             else:
-                self.tv.sprites.remove(fox)
+                self.remove_fox(fox)
         self.foxes = set() # Remove all the foxes
 
     def run_animations(self):
@@ -873,6 +873,8 @@
 
     def remove_fox(self, fox):
         self.foxes.discard(fox)
+        if fox.building:
+            fox.building.remove_predator(fox)
         if fox in self.tv.sprites:
             self.tv.sprites.remove(fox)