def __init__(self, save_file, *args, **kwargs):
super().__init__(*args, **kwargs)
self.changed = True
+ self.changed_fovs = True
self.io = GameIO(self, save_file)
self.tasks = {}
self.thing_types = {}
if t.name in self.faces:
return self.faces[t.name]
else:
- return 'O O' + ' v ' + '>-<'
+ return '/O O\\' + '| oo |' + '\\>--</'
return None
def send_gamestate(self, connection_id=None):
"""Send out game state data relevant to clients."""
# TODO: limit to connection_id if provided
+ print('DEBUG send_gamestate')
self.io.send('TURN ' + str(self.turn))
from plomrogue.mapping import FovMap
import multiprocessing
- pool = multiprocessing.Pool()
- players = []
c_ids = [c_id for c_id in self.sessions]
- for c_id in c_ids:
- players += [self.get_player(c_id)]
+ # Only recalc FOVs for players with ._fov = None
player_fovs = []
- for player in players:
- player.prepare_multiprocessible_fov_stencil()
+ player_fov_ids = []
+ for c_id in c_ids:
+ player = self.get_player(c_id)
+ if player._fov:
+ continue
+ player.prepare_multiprocessible_fov_stencil() #!
player_fovs += [player._fov]
- new_fovs = pool.map(FovMap.init_terrain, [fov for fov in player_fovs])
- for i in range(len(players)):
- players[i]._fov = new_fovs[i]
- pool.close()
- pool.join()
+ player_fov_ids += [player.id_]
+ if len(player_fovs) > 0:
+ print('DEBUG regenerating FOVs')
+ pool = multiprocessing.Pool()
+ new_fovs = pool.map(FovMap.init_terrain, [fov for fov in player_fovs]) #!
+ pool.close()
+ pool.join()
+ for i in range(len(player_fov_ids)):
+ id_ = player_fov_ids[i]
+ player = self.get_thing(id_)
+ player._fov = new_fovs[i]
for c_id in c_ids:
player = self.get_player(c_id)
- visible_terrain = player.fov_stencil_map()
self.io.send('FOV %s' % quote(player.fov_stencil.terrain), c_id)
self.io.send('MAP %s %s %s' % (self.get_map_geometry_shape(),
player.fov_stencil.geometry.size,
- quote(visible_terrain)), c_id)
- visible_control = player.fov_stencil_map('control')
- self.io.send('MAP_CONTROL %s' % quote(visible_control), c_id)
+ quote(player.visible_terrain)), c_id)
+ self.io.send('MAP_CONTROL %s' % quote(player.visible_control), c_id)
for t in [t for t in self.things if player.fov_test(*t.position)]:
target_yx = player.fov_stencil.target_yx(*t.position)
self.io.send('THING %s %s %s %s %s' % (target_yx, t.type_,
if hasattr(t, 'name'):
self.io.send('CHAT ' + quote(t.name + ' left the map.'))
self.things.remove(t)
+ self.changed_fovs = True
to_delete += [connection_id]
for connection_id in to_delete:
del self.sessions[connection_id]
for connection_id in [c_id for c_id in self.sessions
if self.sessions[c_id]['thing_id'] == t.id_]:
self.io.send('PLAY_ERROR ' + quote(str(e)), connection_id)
+ if self.changed_fovs:
+ for t in [t for t in self.things]:
+ t.invalidate_map_view()
if self.changed:
self.turn += 1
# send_gamestate() can be rather expensive, due to among other reasons
datetime.datetime.now() -self.send_gamestate_interval:
self.send_gamestate()
self.changed = False
+ self.changed_fovs = False
self.save()
self.last_send_gamestate = datetime.datetime.now()
write(f, 'THING_INSTALLED %s' % t.id_)
if t.type_ == 'Door' and t.blocking:
write(f, 'THING_DOOR_CLOSED %s' % t.id_)
+ elif t.type_ == 'Hat':
+ write(f, 'THING_HAT_DESIGN %s %s' % (t.id_,
+ quote(t.design)))
elif t.type_ == 'MusicPlayer':
write(f, 'THING_MUSICPLAYER_SETTINGS %s %s %s %s' %
(t.id_, int(t.playing), t.playlist_index, int(t.repeat)))