home
·
contact
·
privacy
projects
/
plomrogue2
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (from parent 1:
22d0a54
)
Recalc FOVs and their map view results only on relevant changes.
author
Christian Heller
<c.heller@plomlompom.de>
Tue, 8 Dec 2020 20:15:21 +0000
(21:15 +0100)
committer
Christian Heller
<c.heller@plomlompom.de>
Tue, 8 Dec 2020 20:15:21 +0000
(21:15 +0100)
plomrogue/commands.py
patch
|
blob
|
history
plomrogue/game.py
patch
|
blob
|
history
plomrogue/mapping.py
patch
|
blob
|
history
plomrogue/tasks.py
patch
|
blob
|
history
plomrogue/things.py
patch
|
blob
|
history
diff --git
a/plomrogue/commands.py
b/plomrogue/commands.py
index 7544c06e03c94018ae975bf65a0ace44e2f4253f..dea07173c6181f2233260823977c95766732bd60 100644
(file)
--- a/
plomrogue/commands.py
+++ b/
plomrogue/commands.py
@@
-57,6
+57,7
@@
def cmd_LOGIN(game, nick, connection_id):
t.position = s.position
break
game.changed = True
t.position = s.position
break
game.changed = True
+ game.changed_fovs = True
cmd_LOGIN.argtypes = 'string'
def cmd_BECOME_ADMIN(game, password, connection_id):
cmd_LOGIN.argtypes = 'string'
def cmd_BECOME_ADMIN(game, password, connection_id):
@@
-84,6
+85,7
@@
def cmd_SET_TILE_CONTROL(game, yx, control_char, connection_id):
map_control = game.get_map(big_yx, 'control')
map_control[little_yx] = control_char
game.changed = True
map_control = game.get_map(big_yx, 'control')
map_control[little_yx] = control_char
game.changed = True
+ game.changed_fovs = True
cmd_SET_TILE_CONTROL.argtypes = 'yx_tuple:nonneg char'
def cmd_THING_PROTECTION(game, thing_id, protection_char, connection_id):
cmd_SET_TILE_CONTROL.argtypes = 'yx_tuple:nonneg char'
def cmd_THING_PROTECTION(game, thing_id, protection_char, connection_id):
@@
-192,14
+194,14
@@
def cmd_GOD_ANNOTATE(game, big_yx, little_yx, msg):
if big_yx not in game.annotations:
game.annotations[big_yx] = {}
game.annotations[big_yx][little_yx] = msg
if big_yx not in game.annotations:
game.annotations[big_yx] = {}
game.annotations[big_yx][little_yx] = msg
- game.changed = True
+
#
game.changed = True
cmd_GOD_ANNOTATE.argtypes = 'yx_tuple yx_tuple:nonneg string'
def cmd_GOD_PORTAL(game, big_yx, little_yx, msg):
if big_yx not in game.portals:
game.portals[big_yx] = {}
game.portals[big_yx][little_yx] = msg
cmd_GOD_ANNOTATE.argtypes = 'yx_tuple yx_tuple:nonneg string'
def cmd_GOD_PORTAL(game, big_yx, little_yx, msg):
if big_yx not in game.portals:
game.portals[big_yx] = {}
game.portals[big_yx][little_yx] = msg
- game.changed = True
+
#
game.changed = True
cmd_GOD_PORTAL.argtypes = 'yx_tuple yx_tuple:nonneg string'
def cmd_MAP_LINE(game, big_yx, y, line):
cmd_GOD_PORTAL.argtypes = 'yx_tuple yx_tuple:nonneg string'
def cmd_MAP_LINE(game, big_yx, y, line):
@@
-238,6
+240,7
@@
def cmd_THING(game, big_yx, little_yx, thing_type, thing_id):
else:
game.things += [t_new]
game.changed = True
else:
game.things += [t_new]
game.changed = True
+ game.changed_fovs = True
cmd_THING.argtypes = 'yx_tuple yx_tuple:nonneg string:thing_type int:nonneg'
def cmd_THING_NAME(game, thing_id, name, pw, connection_id):
cmd_THING.argtypes = 'yx_tuple yx_tuple:nonneg string:thing_type int:nonneg'
def cmd_THING_NAME(game, thing_id, name, pw, connection_id):
diff --git
a/plomrogue/game.py
b/plomrogue/game.py
index 47f09d161ceff332b2e8ad43f086161d9ad75854..6e8afdf83182dded8a25c735b94dc7cdc2a7095a 100755
(executable)
--- a/
plomrogue/game.py
+++ b/
plomrogue/game.py
@@
-117,6
+117,7
@@
class Game(GameBase):
def __init__(self, save_file, *args, **kwargs):
super().__init__(*args, **kwargs)
self.changed = True
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 = {}
self.io = GameIO(self, save_file)
self.tasks = {}
self.thing_types = {}
@@
-213,32
+214,38
@@
class Game(GameBase):
"""Send out game state data relevant to clients."""
# TODO: limit to connection_id if provided
"""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
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]
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 = []
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]
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)
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,
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_,
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_,
@@
-288,6
+295,7
@@
class Game(GameBase):
if hasattr(t, 'name'):
self.io.send('CHAT ' + quote(t.name + ' left the map.'))
self.things.remove(t)
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]
to_delete += [connection_id]
for connection_id in to_delete:
del self.sessions[connection_id]
@@
-304,6
+312,9
@@
class Game(GameBase):
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)
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
if self.changed:
self.turn += 1
# send_gamestate() can be rather expensive, due to among other reasons
@@
-312,6
+323,7
@@
class Game(GameBase):
datetime.datetime.now() -self.send_gamestate_interval:
self.send_gamestate()
self.changed = False
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()
self.save()
self.last_send_gamestate = datetime.datetime.now()
diff --git
a/plomrogue/mapping.py
b/plomrogue/mapping.py
index d4b19b1a8bad56d64aee96d1243aef6592b42e00..2b19f565378d278303a4b772bd599f4f94b9f4e8 100644
(file)
--- a/
plomrogue/mapping.py
+++ b/
plomrogue/mapping.py
@@
-228,7
+228,7
@@
class SourcedMap(Map):
if yxyx[0] not in obstacles:
obstacles[yxyx[0]] = []
obstacles[yxyx[0]] += [yxyx[1]]
if yxyx[0] not in obstacles:
obstacles[yxyx[0]] = []
obstacles[yxyx[0]] += [yxyx[1]]
- for yx in self:
+ for yx in self:
# TODO: iter and source_yxyx expensive, cache earlier?
big_yx, little_yx = self.source_yxyx(yx)
if big_yx in obstacles and little_yx in obstacles[big_yx]:
self.source_map_segment += 'X'
big_yx, little_yx = self.source_yxyx(yx)
if big_yx in obstacles and little_yx in obstacles[big_yx]:
self.source_map_segment += 'X'
diff --git
a/plomrogue/tasks.py
b/plomrogue/tasks.py
index 9d3c23e7b69359da3dd9cdcd23a6cf853eb4ebbc..edfc3d10efddbd1fc4a9d95031b3fd8ea4101aca 100644
(file)
--- a/
plomrogue/tasks.py
+++ b/
plomrogue/tasks.py
@@
-41,6
+41,7
@@
class Task_MOVE(Task):
self.thing.position = self.get_move_target()
if self.thing.carrying:
self.thing.carrying.position = self.thing.position
self.thing.position = self.get_move_target()
if self.thing.carrying:
self.thing.carrying.position = self.thing.position
+ self.thing.game.changed_fovs = True
@@
-56,6
+57,7
@@
class Task_WRITE(Task):
big_yx = self.thing.position[0]
little_yx = self.thing.position[1]
self.thing.game.maps[big_yx][little_yx] = self.args[0]
big_yx = self.thing.position[0]
little_yx = self.thing.position[1]
self.thing.game.maps[big_yx][little_yx] = self.args[0]
+ self.thing.game.changed_fovs = True
@@
-72,6
+74,7
@@
class Task_FLATTEN_SURROUNDINGS(Task):
if not self.thing.game.can_do_tile_with_pw(*yxyx, self.args[0]):
continue
self.thing.game.maps[yxyx[0]][yxyx[1]] = '.'
if not self.thing.game.can_do_tile_with_pw(*yxyx, self.args[0]):
continue
self.thing.game.maps[yxyx[0]][yxyx[1]] = '.'
+ self.thing.game.changed_fovs = True
@@
-100,6
+103,7
@@
class Task_PICK_UP(Task):
to_pick_up = self.thing.game.get_thing(self.args[0])
to_pick_up.position = self.thing.position[:]
self.thing.carrying = to_pick_up
to_pick_up = self.thing.game.get_thing(self.args[0])
to_pick_up.position = self.thing.position[:]
self.thing.carrying = to_pick_up
+ #self.thing.game.changed_fovs = True
@@
-129,6
+133,7
@@
class Task_DROP(Task):
t.accept(self.thing.carrying)
break
self.thing.carrying = None
t.accept(self.thing.carrying)
break
self.thing.carrying = None
+ #self.thing.game.changed_fovs = True
@@
-144,6
+149,7
@@
class Task_DOOR(Task):
t.open()
else:
t.close()
t.open()
else:
t.close()
+ self.thing.game.changed_fovs = True
@@
-163,6
+169,7
@@
class Task_INTOXICATE(Task):
self.thing.send_msg('RANDOM_COLORS')
self.thing.send_msg('CHAT "You are drunk now."')
self.thing.drunk = 10000
self.thing.send_msg('RANDOM_COLORS')
self.thing.send_msg('CHAT "You are drunk now."')
self.thing.drunk = 10000
+ self.thing.game.changed_fovs = True
diff --git
a/plomrogue/things.py
b/plomrogue/things.py
index 116ad696338ffea4fae46fc579426f8e6489048f..23f66ad4a5bb25b5fe297554992116a338879556 100644
(file)
--- a/
plomrogue/things.py
+++ b/
plomrogue/things.py
@@
-100,6
+100,7
@@
class ThingSpawner(Thing):
position=self.position)
self.game.things += [t]
self.game.changed = True
position=self.position)
self.game.things += [t]
self.game.changed = True
+ self.game.changed_fovs = True
@@
-255,6
+256,7
@@
class Thing_MusicPlayer(Thing):
self.playlist_index -= 1
if self.playlist_index < -1:
self.playlist_index = -1
self.playlist_index -= 1
if self.playlist_index < -1:
self.playlist_index = -1
+ self.game.changed = True
return ['removed song']
elif command == 'REWIND':
self.playlist_index = -1
return ['removed song']
elif command == 'REWIND':
self.playlist_index = -1
@@
-309,6
+311,7
@@
class Thing_BottleDeposit(Thing):
msg += 'pick it up and then use "(un-)wear" on it!'
self.sound('BOTTLE DEPOSITOR', msg)
self.game.changed = True
msg += 'pick it up and then use "(un-)wear" on it!'
self.sound('BOTTLE DEPOSITOR', msg)
self.game.changed = True
+ self.game.changed_fovs = True
def accept(self):
self.bottle_counter += 1
def accept(self):
self.bottle_counter += 1
@@
-327,7
+330,12
@@
class ThingAnimate(Thing):
super().__init__(*args, **kwargs)
self.next_task = [None]
self.task = None
super().__init__(*args, **kwargs)
self.next_task = [None]
self.task = None
+ self.invalidate_map_view()
+
+ def invalidate_map_view(self):
self._fov = None
self._fov = None
+ self._visible_terrain = None
+ self._visible_control = None
def set_next_task(self, task_name, args=()):
task_class = self.game.tasks[task_name]
def set_next_task(self, task_name, args=()):
task_class = self.game.tasks[task_name]
@@
-345,11
+353,12
@@
class ThingAnimate(Thing):
if self.drunk == 0:
for c_id in self.game.sessions:
if self.game.sessions[c_id]['thing_id'] == self.id_:
if self.drunk == 0:
for c_id in self.game.sessions:
if self.game.sessions[c_id]['thing_id'] == self.id_:
+ # TODO: refactor with self.send_msg
self.game.io.send('DEFAULT_COLORS', c_id)
self.game.io.send('CHAT "You sober up."', c_id)
self.game.io.send('DEFAULT_COLORS', c_id)
self.game.io.send('CHAT "You sober up."', c_id)
+ self.game.changed_fovs = True
break
self.game.changed = True
break
self.game.changed = True
- self._fov = None
if self.task is None:
self.task = self.get_next_task()
return
if self.task is None:
self.task = self.get_next_task()
return
@@
-393,7
+402,7
@@
class ThingAnimate(Thing):
return True
return False
return True
return False
- def fov_stencil_map(self, map_type
='normal'
):
+ def fov_stencil_map(self, map_type):
visible_terrain = ''
for yx in self.fov_stencil:
if self.fov_stencil[yx] == '.':
visible_terrain = ''
for yx in self.fov_stencil:
if self.fov_stencil[yx] == '.':
@@
-404,6
+413,20
@@
class ThingAnimate(Thing):
visible_terrain += ' '
return visible_terrain
visible_terrain += ' '
return visible_terrain
+ @property
+ def visible_terrain(self):
+ if self._visible_terrain:
+ return self._visible_terrain
+ self._visible_terrain = self.fov_stencil_map('normal')
+ return self._visible_terrain
+
+ @property
+ def visible_control(self):
+ if self._visible_control:
+ return self._visible_control
+ self._visible_control = self.fov_stencil_map('control')
+ return self._visible_control
+
class Thing_Player(ThingAnimate):
class Thing_Player(ThingAnimate):