changeset 502:3d3285918ba1

Disallow collection of items dropped by the other player in netplay, also fixes a longstanding bug where autocollection worked with those items.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 23 Oct 2013 18:24:08 +0200
parents 4778c482f24a
children c622eaf64428
files pytouhou/game/game.pxd pytouhou/game/game.pyx pytouhou/game/item.pxd pytouhou/game/item.pyx pytouhou/game/player.pyx
diffstat 5 files changed, 41 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/game.pxd
+++ b/pytouhou/game/game.pxd
@@ -21,7 +21,7 @@ cdef class Game:
     cpdef disable_spellcard_effect(self)
     cdef void set_player_bomb(self) except *
     cdef void unset_player_bomb(self) except *
-    cpdef drop_bonus(self, double x, double y, long _type, end_pos=*)
+    cpdef drop_bonus(self, double x, double y, long _type, end_pos=*, player=*)
     cdef void autocollect(self, Player player) except *
     cdef void cancel_bullets(self) except *
     cdef void cancel_player_lasers(self) except *
--- a/pytouhou/game/game.pyx
+++ b/pytouhou/game/game.pyx
@@ -129,13 +129,14 @@ cdef class Game:
         self.texts[4] = None
 
 
-    cpdef drop_bonus(self, double x, double y, long _type, end_pos=None):
+    cpdef drop_bonus(self, double x, double y, long _type, end_pos=None, player=None):
         if _type > 6:
             return
         if len(self.items) >= self.nb_bullets_max:
             return #TODO: check
         item_type = self.item_types[_type]
-        self.items.append(Item((x, y), _type, item_type, self, end_pos=end_pos))
+        self.items.append(Item((x, y), _type, item_type, self, end_pos=end_pos,
+                               player=player))
 
 
     cdef void autocollect(self, Player player):
@@ -165,15 +166,19 @@ cdef class Game:
         cdef Player player
         cdef Bullet bullet
         cdef Laser laser
+        cdef Item item
 
         player = min(self.players, key=select_player_key)
         item_type = self.item_types[6]
-        self.items.extend([Item((bullet.x, bullet.y), 6, item_type, self, player=player)
-                             for bullet in self.bullets])
+        items = [Item((bullet.x, bullet.y), 6, item_type, self)
+                 for bullet in self.bullets]
         for laser in self.lasers:
-            self.items.extend([Item(pos, 6, item_type, self, player=player)
-                                 for pos in laser.get_bullets_pos()])
+            items.extend([Item(pos, 6, item_type, self)
+                          for pos in laser.get_bullets_pos()])
             laser.cancel()
+        for item in items:
+            item.autocollect(player)
+        self.items.extend(items)
         self.bullets = []
 
 
--- a/pytouhou/game/item.pxd
+++ b/pytouhou/game/item.pxd
@@ -19,6 +19,7 @@ cdef class Item(Element):
     cdef double angle, speed
     cdef Game _game
     cdef Player player
+    cdef Element target
     cdef Indicator indicator
     cdef Interpolator speed_interpolator, pos_interpolator
 
--- a/pytouhou/game/item.pyx
+++ b/pytouhou/game/item.pyx
@@ -33,7 +33,9 @@ cdef class Indicator(Element):
 
 
 cdef class Item(Element):
-    def __init__(self, start_pos, long _type, ItemType item_type, Game game, double angle=pi/2, Player player=None, end_pos=None):
+    def __init__(self, start_pos, long _type, ItemType item_type, Game game,
+                 double angle=pi/2, player=None, end_pos=None,
+                 target=None):
         Element.__init__(self, start_pos)
 
         self._game = game
@@ -45,19 +47,22 @@ cdef class Item(Element):
         self.angle = angle
         self.indicator = None
 
-        if player is not None:
-            self.autocollect(player)
-        else:
-            self.player = None
+        # The only player allowed to collect that item. If not None,
+        # autocollection is disabled too.
+        self.player = player
+
+        # The player who has autocollected that item.
+        # TODO: do we allow stealing in case another player is in the way?
+        self.target = target
 
-            #TODO: find the formulae in the binary.
-            self.speed_interpolator = None
-            if end_pos:
-                self.pos_interpolator = Interpolator(start_pos, 0,
-                                                     end_pos, 60)
-            else:
-                self.speed_interpolator = Interpolator((-2.,), 0,
-                                                       (0.,), 60)
+        #TODO: find the formulae in the binary.
+        self.speed_interpolator = None
+        if end_pos:
+            self.pos_interpolator = Interpolator(start_pos, 0,
+                                                 end_pos, 60)
+        else:
+            self.speed_interpolator = Interpolator((-2.,), 0,
+                                                   (0.,), 60)
 
         self.sprite.angle = angle
 
@@ -70,14 +75,17 @@ cdef class Item(Element):
 
 
     cdef void autocollect(self, Player player):
-        if self.player is None:
-            self.player = player
+        if self.target is None and self.player is None:
+            self.target = player
             self.speed = player.sht.autocollection_speed
 
 
     cdef void on_collect(self, Player player):
         cdef long level, poc
 
+        if not (self.player is None or self.player is player):
+            return
+
         old_power = player.power
         score = 0
         label = None
@@ -163,8 +171,8 @@ cdef class Item(Element):
             self.speed_interpolator = Interpolator((0.,), 60,
                                                    (3.,), 180)
 
-        if self.player is not None:
-            self.angle = atan2(self.player.y - self.y, self.player.x - self.x)
+        if self.target is not None:
+            self.angle = atan2(self.target.y - self.y, self.target.x - self.x)
             self.x += cos(self.angle) * self.speed
             self.y += sin(self.angle) * self.speed
         elif self.speed_interpolator is None:
--- a/pytouhou/game/player.pyx
+++ b/pytouhou/game/player.pyx
@@ -260,7 +260,7 @@ cdef class Player(Element):
                     self.continues_used += 1
 
                     for i in xrange(5):
-                        self._game.drop_bonus(self.x, self.y, 4,
+                        self._game.drop_bonus(self.x, self.y, 4, player=self,
                                               end_pos=(self._game.prng.rand_double() * 288 + 48,
                                                        self._game.prng.rand_double() * 192 - 64))
                     self.score = 0
@@ -272,11 +272,11 @@ cdef class Player(Element):
                     self.graze = 0
                     self.points = 0
                 else:
-                    self._game.drop_bonus(self.x, self.y, 2,
+                    self._game.drop_bonus(self.x, self.y, 2, player=self,
                                           end_pos=(self._game.prng.rand_double() * 288 + 48, # 102h.exe@0x41f3dc
                                                    self._game.prng.rand_double() * 192 - 64))        # @0x41f3
                     for i in xrange(5):
-                        self._game.drop_bonus(self.x, self.y, 0,
+                        self._game.drop_bonus(self.x, self.y, 0, player=self,
                                               end_pos=(self._game.prng.rand_double() * 288 + 48,
                                                        self._game.prng.rand_double() * 192 - 64))