# HG changeset patch # User Emmanuel Gil Peyrot # Date 1382545448 -7200 # Node ID 3d3285918ba1df85eb713847f1fc953ce6ff993c # Parent 4778c482f24a9707766252c14997e7f1895e9d39 Disallow collection of items dropped by the other player in netplay, also fixes a longstanding bug where autocollection worked with those items. diff --git a/pytouhou/game/game.pxd b/pytouhou/game/game.pxd --- 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 * diff --git a/pytouhou/game/game.pyx b/pytouhou/game/game.pyx --- 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 = [] diff --git a/pytouhou/game/item.pxd b/pytouhou/game/item.pxd --- 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 diff --git a/pytouhou/game/item.pyx b/pytouhou/game/item.pyx --- 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: diff --git a/pytouhou/game/player.pyx b/pytouhou/game/player.pyx --- 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))