import socket
import threading
from plomrogue.parser import ArgError, Parser
-from plomrogue.commands import cmd_MAP, cmd_THING_POS, cmd_PLAYER_ID
+from plomrogue.commands import (cmd_MAP, cmd_THING_POS, cmd_PLAYER_ID,
+ cmd_THING_HEALTH)
from plomrogue.game import Game, WorldBase
from plomrogue.mapping import MapHex
from plomrogue.io import PlomSocket
'MAP': cmd_MAP,
'PICKABLE_ITEMS': cmd_PICKABLE_ITEMS,
'THING_TYPE': cmd_THING_TYPE,
+ 'THING_HEALTH': cmd_THING_HEALTH,
'THING_POS': cmd_THING_POS}
self.log_text = ''
self.do_quit = False
self.safe_write((str(self.tui.game.world.turn), curses.color_pair(2)))
+class HealthWidget(Widget):
+
+ def draw(self):
+ if hasattr(self.tui.game.world.player, 'health'):
+ self.safe_write((str(self.tui.game.world.player.health),
+ curses.color_pair(2)))
+
+
class TextLineWidget(Widget):
def __init__(self, text_line, *args, **kwargs):
edit_widget.children += [edit_line_widget]
turn_widget = TextLineWidget('TURN:', self, (2, 0), (1, 20))
turn_widget.children += [TurnWidget(self, (2, 6), (1, 14), ['turn'])]
- log_widget = LogWidget(self, (4, 0), (None, 20), ['log'])
- descriptor_widget = DescriptorWidget(self, (4, 0), (None, 20),
+ health_widget = TextLineWidget('HEALTH:', self, (3, 0), (1, 20))
+ health_widget.children += [HealthWidget(self, (3, 8), (1, 12), ['turn'])]
+ log_widget = LogWidget(self, (5, 0), (None, 20), ['log'])
+ descriptor_widget = DescriptorWidget(self, (5, 0), (None, 20),
['map'], False)
map_widget = MapWidget(self, (0, 21), (None, None), ['map'])
inventory_widget = InventoryWidget(self, (0, 21), (None, None),
['inventory'], False)
pickable_items_widget = PickableItemsWidget(self, (0, 21), (None, None),
['pickable_items'], False)
- top_widgets = [edit_widget, turn_widget, log_widget,
+ top_widgets = [edit_widget, turn_widget, health_widget, log_widget,
descriptor_widget, map_widget, inventory_widget,
pickable_items_widget]
popup_widget = PopUpWidget(self, (0, 0), (1, 1), visible=False)
t.inventory = ids # TODO: test whether valid IDs
cmd_THING_INVENTORY.argtypes = 'int:nonneg seq:int:nonneg'
+def cmd_THING_HEALTH(game, id_, health):
+ t = game.world.get_thing(id_)
+ t.health = health
+cmd_THING_HEALTH.argtypes = 'int:nonneg int:nonneg'
+
def cmd_GET_PICKABLE_ITEMS(game, connection_id):
pickable_ids = game.world.player.get_pickable_items()
if len(pickable_ids) > 0:
write(f, 'THING_TYPE %s %s' % (thing.id_, thing.type_))
write(f, 'THING_POS %s %s' % (thing.id_,
stringify_yx(thing.position)))
+ if hasattr(thing, 'health'):
+ write(f, 'THING_HEALTH %s %s' % (thing.id_, thing.health))
if len(thing.inventory) > 0:
write(f, 'THING_INVENTORY %s %s' %
(thing.id_,','.join([str(i) for i in thing.inventory])))
from plomrogue.tasks import Task_WAIT, Task_MOVE, Task_PICKUP, Task_DROP
-from plomrogue.errors import ArgError
-from plomrogue.commands import (cmd_GEN_WORLD, cmd_GET_GAMESTATE, cmd_MAP,
- cmd_MAP, cmd_THING_TYPE, cmd_THING_POS,
- cmd_THING_INVENTORY, cmd_GET_PICKABLE_ITEMS,
- cmd_TERRAIN_LINE, cmd_PLAYER_ID, cmd_TURN,
- cmd_SWITCH_PLAYER, cmd_SAVE)
+from plomrogue.errors import ArgError, GameError
+from plomrogue.commands import (cmd_GEN_WORLD, cmd_GET_GAMESTATE,
+ cmd_MAP, cmd_MAP, cmd_THING_TYPE,
+ cmd_THING_POS, cmd_THING_INVENTORY,
+ cmd_THING_HEALTH,
+ cmd_GET_PICKABLE_ITEMS,
+ cmd_TERRAIN_LINE, cmd_PLAYER_ID,
+ cmd_TURN, cmd_SWITCH_PLAYER, cmd_SAVE)
from plomrogue.mapping import MapHex
from plomrogue.parser import Parser
from plomrogue.io import GameIO
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.player_id = 0
+ self.player_is_alive = True
@property
def player(self):
(after incrementing the world turn) all that come before the
player; then the player's .proceed() is run, and if it does
not finish his task, the loop starts at the beginning. Once
- the player's task is finished, the loop breaks.
+ the player's task is finished, or the player is dead, the loop
+ breaks.
+
"""
while True:
player_i = self.things.index(self.player)
for thing in self.things[:player_i]:
thing.proceed()
self.player.proceed(is_AI=False)
- if self.player.task is None:
+ if self.player.task is None or not self.player_is_alive:
break
def make_new(self, yx, seed):
'MAP': cmd_MAP,
'THING_TYPE': cmd_THING_TYPE,
'THING_POS': cmd_THING_POS,
+ 'THING_HEALTH': cmd_THING_HEALTH,
'THING_INVENTORY': cmd_THING_INVENTORY,
'TERRAIN_LINE': cmd_TERRAIN_LINE,
'GET_PICKABLE_ITEMS': cmd_GET_PICKABLE_ITEMS,
self.io.send('THING_TYPE %s %s' % (thing.id_, thing.type_))
self.io.send('THING_POS %s %s' % (thing.id_,
stringify_yx(thing.position)))
+ if hasattr(thing, 'health'):
+ self.io.send('THING_HEALTH %s %s' % (thing.id_,
+ thing.health))
if len(self.world.player.inventory) > 0:
self.io.send('PLAYER_INVENTORY %s' %
','.join([str(i) for i in self.world.player.inventory]))
return p
def cmd_TASK_colon(task_name, game, *args):
+ if not game.world.player_is_alive:
+ raise GameError('You are dead.')
game.world.player.set_task(task_name, args)
game.proceed()
self.task.check() # will throw GameError if necessary
def proceed(self, is_AI=True):
- """Further the thing in its tasks.
+ """Further the thing in its tasks, decrease its health.
- Decrements .task.todo; if it thus falls to <= 0, enacts method
- whose name is 'task_' + self.task.name and sets .task =
- None. If is_AI, calls .decide_task to decide a self.task.
-
- Before doing anything, ensures an empty map visibility stencil
- and checks that task is still possible, and aborts it
+ First, ensures an empty map, decrements .health and kills
+ thing if crossing zero (removes from self.world.things for AI
+ thing, or unsets self.world.player_is_alive for player thing);
+ then checks that self.task is still possible and aborts if
otherwise (for AI things, decides a new task).
+ Then decrements .task.todo; if it thus falls to <= 0, enacts
+ method whose name is 'task_' + self.task.name and sets .task =
+ None. If is_AI, calls .decide_task to decide a self.task.
+
"""
self._stencil = None
+ self.health -= 1
+ if self.health <= 0:
+ if self is self.world.player:
+ self.world.player_is_alive = False
+ else:
+ del self.world.things[self.world.things.index(self)]
+ return
try:
self.task.check()
except GameError as e:
class ThingHuman(ThingAnimate):
type_ = 'human'
+ health = 100
class ThingMonster(ThingAnimate):
type_ = 'monster'
+ health = 50