summaryrefslogtreecommitdiff
path: root/subscriber.py
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2015-09-01 20:47:11 +0200
committerFlorian Jung <flo@windfisch.org>2015-09-01 20:48:03 +0200
commit7a836f4a0a68188a1486b669c4cd437b5f592a5d (patch)
tree666d7867967e8d6fdc04aca6b18d8a95a077f33c /subscriber.py
parentf99e10cff97afdc3e6ef07db22cf5f7fd442e067 (diff)
parent7c1180a7b58e7b8c17c8dab297058d0c001386c6 (diff)
Merge branch 'master' into pathfinding
Diffstat (limited to 'subscriber.py')
-rw-r--r--subscriber.py190
1 files changed, 190 insertions, 0 deletions
diff --git a/subscriber.py b/subscriber.py
index a637e67..b89a6a9 100644
--- a/subscriber.py
+++ b/subscriber.py
@@ -1,5 +1,7 @@
from log import log
+from collections import deque
import sys
+import mechanics
class DummySubscriber:
def on_connect_error(self,s):
@@ -65,3 +67,191 @@ class DummySubscriber:
def on_debug_line(self,x,y):
log("debug line")
+class CellHistory:
+ def __init__(self):
+ self.poslog = deque(maxlen=300)
+ self.stale = False
+
+class OtherPlayer:
+ def __init__(self, playerid):
+ self.playerid = playerid
+ self.cells = set()
+
+class EnhancingSubscriber(DummySubscriber):
+ def __init__(self):
+ self.c = None
+ self.history = {}
+ self.time = 0
+ self.victims = {}
+
+ def set_client(self,c):
+ self.c = c
+
+ def cleanup_victims(self):
+ delete = []
+
+ for eater in self.victims:
+ self.victims[eater] = list(filter(lambda v : v[1] < self.time - 100, self.victims[eater]))
+ if len(self.victims[eater]) == 0:
+ delete += [eater]
+
+ for eater in delete:
+ del self.victims[eater]
+
+ def on_cell_eaten(self, eater_id, eaten_id):
+ if eater_id in self.c.world.cells and self.c.world.cells[eater_id].is_virus:
+ print("virus ate something!")
+
+ if eater_id not in self.victims:
+ self.victims[eater_id] = []
+
+ self.victims[eater_id] += [(self.c.world.cells[eaten_id], self.time)]
+
+ def on_world_update_post(self):
+ self.c.world.time = self.time
+ self.time += 1
+
+ if self.time % 100 == 0:
+ self.cleanup_victims()
+
+ # create and purge poslog history, movement and movement_angle
+ for cid in self.history:
+ self.history[cid].stale = True
+
+ for cid in self.c.world.cells:
+ if cid not in self.history:
+ self.history[cid] = CellHistory()
+
+ self.history[cid].poslog.append(self.c.world.cells[cid].pos.copy())
+ self.c.world.cells[cid].poslog = self.history[cid].poslog
+
+ self.history[cid].stale = False
+
+ self.history = {k: v for k, v in self.history.items() if v.stale == False}
+
+
+ for cid in self.c.world.cells:
+ cell = self.c.world.cells[cid]
+
+ if not hasattr(cell, "spawntime"):
+ cell.spawntime = self.c.world.time
+
+ try:
+ oldpos = cell.poslog[-3-1]
+ cell.movement = (cell.pos - oldpos)/3
+ cell.movement_angle = cell.movement.angle()
+ except (AttributeError, IndexError):
+ pass
+
+
+ # create OtherPlayer entries
+ otherplayers = {}
+ for cell in self.c.world.cells.values():
+ playerid = None
+ if not cell.is_food and not cell.is_ejected_mass and not cell.is_virus:
+ playerid = (cell.name, cell.color)
+ elif cell.is_virus:
+ playerid = "virus"
+ elif cell.is_food:
+ playerid = "food"
+ elif cell.is_ejected_mass:
+ playerid = "ejected mass"
+ else:
+ playerid = "???"
+
+ if playerid not in otherplayers:
+ otherplayers[playerid] = OtherPlayer(playerid)
+
+ cell.player = otherplayers[playerid]
+ cell.player.cells.add(cell)
+
+ # detect split cells and clean up obsolete parent references
+ for cell in self.c.world.cells.values():
+ # create attribute if not already there
+ try:
+ cell.parent = cell.parent
+ except:
+ cell.parent = None
+ cell.calmed_down = True
+
+ # clean up obsolete parent references
+ if cell.parent and cell.parent.cid not in self.c.world.cells:
+ cell.parent = None
+
+ # find split cells
+ is_split = False
+ if not cell.is_food and not cell.is_ejected_mass and not cell.is_virus:
+ try:
+ if cell.parent == None and cell.movement.len() > 2 * mechanics.speed(cell.size):
+ print("looks like a split!"+str(cell.movement.len() / mechanics.speed(cell.size)))
+ is_split = True
+ except AttributeError:
+ pass
+
+ if is_split:
+ history_len = len(cell.poslog)
+ cell.parent = min(cell.player.cells, key=lambda c : (c.poslog[-history_len] - cell.poslog[-history_len]).len() if c != cell and len(c.poslog) >= history_len else float('inf'))
+ try:
+ cell.shoot_vec = cell.parent.movement.copy()
+ except:
+ cell.shoot_vec = None
+ cell.calmed_down = False
+
+ elif cell.is_virus:
+ try:
+ if cell.parent == None and cell.movement.len() > 0:
+ print("split virus!")
+ is_split = True
+ except AttributeError:
+ pass
+
+ if is_split:
+ cell.parent = min(cell.player.cells, key=lambda c : (c.pos - cell.poslog[0]).len() if c != cell else float('inf'))
+ try:
+ last_feed = self.victims[cell.parent.cid][-1][0]
+ if not last_feed.is_ejected_mass:
+ print("wtf, last virus feed was not ejected mass?!")
+ raise KeyError
+ else:
+ cell.shoot_vec = cell.parent.pos - last_feed.poslog[0]
+ cell.shoot_vec2 = last_feed.poslog[-1] - last_feed.poslog[0]
+ try:
+ pos_when_shot = last_feed.parent.poslog[-len(last_feed.poslog)]
+ cell.shoot_vec3 = cell.parent.pos - pos_when_shot
+ except:
+ print("MOAAAHH")
+ cell.shoot_vec3 = None
+ except KeyError:
+ print("wtf, no last virus feed?!")
+ cell.shoot_vec = None
+ cell.shoot_vec2 = None
+ cell.shoot_vec3 = None
+
+ cell.calmed_down = False
+
+ elif cell.is_ejected_mass:
+ try:
+ if cell.parent == None and cell.movement.len() > 0:
+ print("ejected mass!")
+ is_split = True
+ except AttributeError:
+ pass
+
+ if is_split:
+ history_len = len(cell.poslog)
+ try:
+ cell.parent = min(filter(lambda c : not c.is_ejected_mass and not c.is_food and not c.is_virus and c.color == cell.color, self.c.world.cells.values()), key=lambda c : (c.poslog[-history_len] - cell.poslog[-history_len]).len() if len(c.poslog) >= history_len else float('inf'))
+ try:
+ cell.shoot_vec = cell.parent.movement.copy()
+ except:
+ cell.shoot_vec = None
+ cell.calmed_down = False
+ except ValueError:
+ # if no possible parents are found, min will raise a ValueError. ignore that.
+ pass
+
+ if is_split:
+ cell.spawnpoint = cell.pos.copy()
+ cell.parentsize_when_spawned = cell.parent.size if cell.parent != None else None
+ cell.parentpos_when_spawned = cell.parent.pos.copy() if cell.parent != None else None
+