changeset 99:59a9af792127

dropping items
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Mon, 06 Jan 2014 14:51:46 +0100
parents 59306467bb73
children 542a1300c4e6
files fujo/display.py fujo/items.py fujo/level.py fujo/mobs.py fujo/player.py fujo/things.py
diffstat 6 files changed, 67 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/fujo/display.py	Mon Jan 06 14:11:34 2014 +0100
+++ b/fujo/display.py	Mon Jan 06 14:51:46 2014 +0100
@@ -67,8 +67,8 @@
     def update(self):
         self.windows.clear(self.screen, self.windows_background)
         self.labels.clear(self.screen, self.windows_background)
-        self.sprites.clear(self.screen, self.background)
-        self.shadows.clear(self.screen, self.background)
+        self.sprites.clear(self.screen, self.windows_background)
+        self.shadows.clear(self.screen, self.windows_background)
         self.sprites.update(self)
         self.labels.update()
         self.shadows.update()
--- a/fujo/items.py	Mon Jan 06 14:11:34 2014 +0100
+++ b/fujo/items.py	Mon Jan 06 14:51:46 2014 +0100
@@ -37,16 +37,17 @@
         self.image = image
         self.kill()
 
-    def throw_anim(self, pos, steps, direction):
+    def throw_anim(self, pos, steps, direction, drop=False):
         self.rect.midbottom = 24 * pos[0], 16 * pos[1] - 3
         for step in xrange(steps):
             for frame in xrange(2):
                 self.rect.move_ip(DX[direction] * 12, DY[direction] * 8)
                 self.depth = self.rect.bottom + 8
                 yield
-        self.rect.midbottom = 24 * pos[0], 16 * pos[1] + 5
+        self.rect.midbottom = 24 * self.pos[0], 16 * self.pos[1] + 5
         self.depth = self.rect.bottom
-        self.kill()
+        if not drop:
+            self.kill()
 
     def pick_up(self, level):
         self.animation = self.pickup_anim()
@@ -57,9 +58,9 @@
     def use(self, level):
         return True
 
-    def throw(self, level, pos, mob, steps, direction):
-        self.animation = self.throw_anim(self.pos, steps, direction)
-        self.set_pos(pos)
+    def throw(self, level, pos, mob):
+        if mob:
+            return True
 
 
 def _calm_mob(mob):
@@ -84,11 +85,12 @@
         level.player.label("%d" % (self.nutrition //10), (0x22, 0xff, 0x00))
         return True
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(Food, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(Food, self).throw(level, pos, mob)
         # Throwing food at monsters calms them down.
         if mob:
             _calm_mob(mob)
+            return True
 
 @Item.register
 class Onigiri(Food):
@@ -134,10 +136,11 @@
         # Equipping doesn't discard.
         return False
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(Weapon, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(Weapon, self).throw(level, pos, mob)
         if mob:
             mob.wound(self.damage * 2)
+            return True
 
     def save(self):
         data = super(Weapon, self).save()
@@ -207,10 +210,12 @@
         self.__class__.identified = True
         level.player.label(self.name)
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(Spell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(Spell, self).throw(level, pos, mob)
         level.player.label(self.name)
-        self.__class__.identified = True
+        if mob:
+            self.__class__.identified = True
+            return True
 
     def save(self):
         data = super(Spell, self).save()
@@ -232,11 +237,12 @@
         level.player.wound(random.randint(3, 8))
         return True
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(FireSpell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(FireSpell, self).throw(level, pos, mob)
         if mob:
             mob.wound(random.randint(1, 5))
             mob.add_behavior(behaviors.Panic(10))
+            return True
 
 
 @Item.register
@@ -255,8 +261,8 @@
         level.place_mob(level.player, pos)
         return True
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(TeleportSpell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(TeleportSpell, self).throw(level, pos, mob)
         if mob:
             mob.add_behavior(behaviors.Confused(10))
             for pos in level.empty:
@@ -267,6 +273,7 @@
             del level.mobs[mob.pos]
             mob.pos = None
             level.place_mob(mob, pos)
+            return True
 
 @Item.register
 class KnowledgeSpell(Spell):
@@ -278,14 +285,16 @@
             item.__class__.identified = True
         return True
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(KnowledgeSpell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(KnowledgeSpell, self).throw(level, pos, mob)
         if mob:
             mob.add_behavior(behaviors.Confused(10))
         else:
             for row in level.explored:
                 row[:] = [1] * len(row)
         level.explored[level.player.pos[1]][level.player.pos[0]] = 0
+        self.__class__.identified = True
+        return True
 
 @Item.register
 class SoothingSpell(Spell):
@@ -301,14 +310,15 @@
         level.player.label("%d" % healing, (0x22, 0xff, 0x00))
         return True
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(SoothingSpell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(SoothingSpell, self).throw(level, pos, mob)
         if mob:
             healing = mob.max_health - mob.health
             mob.health = mob.max_health
             _calm_mob(mob)
             mob.add_behavior(behaviors.Sleep(10))
             mob.label("%d" % healing, (0x22, 0xff, 0x00))
+            return True
 
 
 @Item.register
@@ -324,10 +334,11 @@
             return True
         return False
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(TransformSpell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(TransformSpell, self).throw(level, pos, mob)
         if mob:
             mob.add_behavior(behaviors.Hide())
+            return True
 
 
 @Item.register
@@ -342,11 +353,13 @@
             return True
         return False
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(SharpenSpell, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(SharpenSpell, self).throw(level, pos, mob)
         for mob in level.mobs.values():
             if mob != level.player:
                 mob.wound(0)
+        self.__class__.identified = True
+        return True
 
 
 class Armor(Item):
@@ -363,11 +376,12 @@
             level.player.equip_armor(self)
         return False
 
-    def throw(self, level, pos, mob, steps, direction):
-        super(Armor, self).throw(level, pos, mob, steps, direction)
+    def throw(self, level, pos, mob):
+        super(Armor, self).throw(level, pos, mob)
         if mob:
             _calm_mob(mob)
             mob.add_behavior(behaviors.Sleep(10))
+            return True
 
 @Item.register
 class LuckyCharm(Armor):
--- a/fujo/level.py	Mon Jan 06 14:11:34 2014 +0100
+++ b/fujo/level.py	Mon Jan 06 14:51:46 2014 +0100
@@ -16,7 +16,6 @@
     ((1, 22), (5, 7)), ((7, 22), (5, 7)), ((15, 22), (5, 7)),
 ]
 MONSTERS = [
-    [mobs.Kappa],
     [mobs.Bat, mobs.Martian],
     [mobs.Bat, mobs.Martian, mobs.Kappa, mobs.Tanuki],
     [mobs.Martian, mobs.Kappa, mobs.Tanuki, mobs.Tengu],
@@ -132,16 +131,20 @@
 
     def drop_item(self, pos, item):
         if self.things.get(pos):
+            item.kill()
             return
         self.things[pos] = item
         item.pos = None
         item.set_pos(pos)
+        self.player.new_things.append(item)
 
     def throw_item(self, thrower, item, direction):
+        last_pos = thrower.pos
         pos = dpos(thrower.pos, direction)
         item.set_pos(thrower.pos)
         steps = 0
         while not self.is_blocked(pos):
+            last_pos = pos
             pos = dpos(pos, direction)
             steps += 1
         mob = self.mobs.get(pos)
@@ -149,7 +152,10 @@
             mob = None
         if mob:
             mob.item_thrown(self, item)
-        item.throw(self, pos, mob, steps, direction)
+        drop = not item.throw(self, pos, mob)
+        item.animation = item.throw_anim(thrower.pos, steps, direction, drop)
+        if drop:
+            self.drop_item(last_pos, item)
 
     def populate(self):
         self.empty = []
@@ -192,8 +198,11 @@
         self.place_thing(things.Hole(), pos)
         self.place_mob(self.player, pos)
 
+    def is_wall(self, pos):
+        return self.walls[pos[1]][pos[0]] or self.mobs.get(pos)
+
     def is_blocked(self, pos):
-        return self.walls[pos[1]][pos[0]] or self.mobs.get(pos)
+        return self.is_wall(pos) or self.mobs.get(pos)
 
     def is_explored(self, pos):
         return self.explored[pos[1]][pos[0]]
--- a/fujo/mobs.py	Mon Jan 06 14:11:34 2014 +0100
+++ b/fujo/mobs.py	Mon Jan 06 14:51:46 2014 +0100
@@ -157,8 +157,6 @@
 
     def update(self, display):
         super(Monster, self).update(display)
-        if self.dead and self.item:
-            display.spawn_thing(self.item)
         try:
             self.animation.next()
         except StopIteration:
--- a/fujo/player.py	Mon Jan 06 14:11:34 2014 +0100
+++ b/fujo/player.py	Mon Jan 06 14:51:46 2014 +0100
@@ -6,7 +6,6 @@
 import pygame
 
 from . import items
-from . import things
 from . import window
 from . import mobs
 from .util import DX, DY, COLOR_RED, COLOR_GREEN, dpos
@@ -45,6 +44,8 @@
             items.Bento(),
             spell,
         ]
+        self.new_sprites = []
+        self.new_things = []
 
     @property
     def attack(self):
@@ -157,7 +158,7 @@
                 submenu = window.Menu((display.size[0] - 200, 36, 96, 32), [
                     ('use', item.action),
                     ('throw', "Throw"),
-                    ('discard', "Discard"),
+                    ('drop', "Drop"),
                 ], 2)
                 action = submenu.run(display)
                 submenu.kill()
@@ -168,8 +169,9 @@
         menu.kill()
         if not item or not action:
             return False
-        elif action == 'discard':
+        elif action == 'drop':
             self.discard_item(item)
+            level.drop_item(self.pos, item)
         elif action == 'use':
             if item.use(level):
                 self.discard_item(item)
@@ -201,6 +203,12 @@
 
     def update(self, display):
         super(Player, self).update(display)
+        for thing in self.new_things:
+            display.spawn_thing(thing)
+        self.new_things[:] = []
+        for sprite in self.new_sprites:
+            display.sprites.add(sprite)
+        self.new_sprites[:] = []
         if self.animation:
             try:
                 self.animation.next()
--- a/fujo/things.py	Mon Jan 06 14:11:34 2014 +0100
+++ b/fujo/things.py	Mon Jan 06 14:51:46 2014 +0100
@@ -42,8 +42,8 @@
     def set_pos(self, pos):
         if self.pos is None:
             self.rect.midbottom = 24 * pos[0], 16 * pos[1] + 5
+            self.depth = self.rect.bottom
         self.pos = pos
-        self.depth = self.rect.bottom
 
     def save(self):
         data = super(Thing, self).save()