changeset 60:2635db8e5a63

tanukis turn into items
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Wed, 01 Jan 2014 18:10:02 +0100
parents ad3292477a77
children a2a594788501
files fujo/display.py fujo/level.py fujo/mobs.py fujo/monsters.png
diffstat 4 files changed, 94 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/fujo/display.py	Wed Jan 01 17:19:34 2014 +0100
+++ b/fujo/display.py	Wed Jan 01 18:10:02 2014 +0100
@@ -105,10 +105,6 @@
             self.shadows.add(things.Shadow(mob))
 
     def render_level(self, level):
-        if level.depth == 5:
-            theme = 1
-        else:
-            theme = 0
         self.background = pygame.Surface(self.size)
         self.overlay = pygame.Surface(self.size, pygame.SRCALPHA)
         self.fog = pygame.Surface(self.size)
@@ -121,9 +117,11 @@
         render_layer(self.background, level.walls, RES.wall_tiles[0:],
                      lambda c: c == 0, 0, pygame.BLEND_MULT)
         render_layer(self.overlay, level.walls,
-                     RES.wall_tiles[30 * theme + 15:], lambda c: c != 0, -8)
+                     RES.wall_tiles[30 * level.looks + 15:],
+                     lambda c: c != 0, -8)
         render_layer(self.background, level.walls,
-                     RES.wall_tiles[30 * theme + 30:], lambda c: c != 0, -8)
+                     RES.wall_tiles[30 * level.looks + 30:],
+                     lambda c: c != 0, -8)
         for mob in level.mobs.values():
             self.spawn_mob(mob)
         for thing in level.things.values():
--- a/fujo/level.py	Wed Jan 01 17:19:34 2014 +0100
+++ b/fujo/level.py	Wed Jan 01 18:10:02 2014 +0100
@@ -13,9 +13,19 @@
     ((1, 12), (5, 7)), ((7, 12), (5, 7)), ((15, 12), (5, 7)),
     ((1, 22), (5, 7)), ((7, 22), (5, 7)), ((15, 22), (5, 7)),
 ]
+MONSTERS = [
+    [mobs.Tanuki],
+    [mobs.Bat, mobs.Martian],
+    [mobs.Bat, mobs.Martian, mobs.Kappa, mobs.Tanuki],
+    [mobs.Martian, mobs.Kappa, mobs.Tanuki, mobs.Tengu],
+    [mobs.Kappa, mobs.Tengu, mobs.Tanuki, mobs.Shadow],
+    [mobs.Ghost, mobs.Tengu, mobs.Shadow],
+]
 
 
 class Level(object):
+    looks = 0
+
     def __init__(self, depth):
         self.size = 21, 32
         self.depth = depth
@@ -92,8 +102,20 @@
     def attack_mob(self, attacker, defender):
         attack = random.randint(0, attacker.attack)
         defense = random.randint(0, defender.defense)
+        damage = 0
         if attack > defense:
-            defender.wound(random.randint(1, attacker.damage + 1))
+            damage = attacker.damage + 1
+            defender.wound(random.randint(1, damage))
+        for mob in self.mobs.values():
+            if mob not in (attacker, defender):
+                mob.mob_attacked(self, defender, damage)
+
+    def pick_item(self, thing):
+        for mob in self.mobs.values():
+            mob.item_picked(self, thing)
+        del self.things[thing.pos]
+        thing.picked_up = True
+        return thing.item()
 
     def populate(self):
         self.empty = []
@@ -102,19 +124,11 @@
                 for x in xrange(sx, sx + w + 1):
                     self.empty.append((x, y))
         random.shuffle(self.empty)
-        if self.depth < 5:
-            self.place_thing(things.Ladder(), self.empty.pop())
-            for i in xrange(3 + 5 * self.depth):
-                Monster = random.choice(mobs.MONSTERS)
-                self.place_mob(Monster(), self.empty.pop())
-            for i in xrange(10 - 2 * self.depth):
-                kind = random.choice(items.ITEMS)
-                self.place_thing(things.Item(kind), self.empty.pop())
-            for i in xrange(2):
-                # Guaranteed food.
-                kind = random.choice(items.FOOD)
-                self.place_thing(things.Item(kind), self.empty.pop())
-        else:
+        try:
+            monsters = MONSTERS[self.depth]
+        except IndexError:
+            # Final level
+            self.looks = 1
             boss = mobs.Boss()
             self.place_mob(boss, self.empty.pop())
             for i in xrange(2):
@@ -126,6 +140,18 @@
             for i in xrange(2):
                 kind = random.choice(items.ARMOR)
                 self.place_thing(things.Item(kind), self.empty.pop())
+        else:
+            self.place_thing(things.Ladder(), self.empty.pop())
+            for i in xrange(3 + 5 * self.depth):
+                Monster = random.choice(monsters)
+                self.place_mob(Monster(), self.empty.pop())
+            for i in xrange(10 - 2 * self.depth):
+                kind = random.choice(items.ITEMS)
+                self.place_thing(things.Item(kind), self.empty.pop())
+            for i in xrange(2):
+                # Guaranteed food.
+                kind = random.choice(items.FOOD)
+                self.place_thing(things.Item(kind), self.empty.pop())
         for i in xrange(12):
             self.place_thing(random.choice(things.DEBRIS)(), self.empty.pop())
 
--- a/fujo/mobs.py	Wed Jan 01 17:19:34 2014 +0100
+++ b/fujo/mobs.py	Wed Jan 01 18:10:02 2014 +0100
@@ -55,6 +55,12 @@
         self.new_labels.append(
             window.Label(place, text, color, delay, offset))
 
+    def item_picked(self, level, thing):
+        return
+
+    def mob_attacked(self, level, mob, damage):
+        return
+
 
 class Monster(Mob):
     max_health = 5
@@ -88,6 +94,20 @@
             del level.mobs[self.pos]
             self.animation = self.death_anim()
 
+    def item_picked(self, level, thing):
+        # Picking up items makes nearby monsters angry
+        if self.asleep:
+            return
+        if dist(self.pos, thing.pos) < 6:
+            self.angry += 10
+
+    def mob_attacked(self, level, mob, damage):
+        # Attacking other monsters makes nearby monsters angry
+        if self.asleep:
+            return
+        if dist(self.pos, mob.pos) < 6:
+            self.angry += 10
+
     def act(self, level):
         if self.asleep:
             if level.explored[self.pos[1]][self.pos[0]]:
@@ -197,6 +217,35 @@
 class Tanuki(Monster):
     looks = 6
 
+    def __init__(self):
+        super(Tanuki, self).__init__()
+        self.animation = self.hide_anim()
+        self.hidden = True
+
+    def hide_anim(self):
+        # Look like food or bush
+        item = random.choice([4, 5, 9, 10, 11])
+        self.image = RES.things[item]
+        while True:
+            yield
+
+    def act(self, level):
+        if self.angry:
+            self.hidden = False
+        if self.hidden:
+            return
+        return super(Tanuki, self).act(level)
+
+    def item_picked(self, level, thing):
+        # Tanukis don't mind picking up items
+        return
+
+    def mob_attacked(self, level, mob, damage):
+        # Tanukis don't mind others being attacked when they hide
+        if self.hidden:
+            return
+        super(Tanuki, self).mob_attacked(level, mob, damage)
+
 
 class Shadow(Monster):
     looks = 7
@@ -284,15 +333,9 @@
     def pick_item(self, level):
         thing = level.things.get(self.pos)
         if thing and thing.item:
-            del level.things[self.pos]
-            thing.picked_up = True
-            item = thing.item()
+            item = level.pick_item(thing)
             self.label(item.get_name(), delay=2, place=thing.rect.midtop)
             self.items.append(item)
-            for mob in level.mobs.values():
-                # Picking up items makes monsters angry!
-                if mob != self and dist(self.pos, mob.pos) < 8:
-                    mob.angry += 10
 
     def act(self, level, display):
         if self.dead:
Binary file fujo/monsters.png has changed