-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplayer.py
146 lines (121 loc) · 4.73 KB
/
player.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
''' Basic player character functionality. '''
from ability import Ability, ABIL_JUMP
from actor import Actor
import crender.colors
MAX_HP = 3
class Player(Actor):
''' The player character class.
Attributes:
health (int): The player's current HP; 0 implies dead.
abilities (list<Ability>): A list of the player's current abilities & their state.
'''
def __init__(self):
super().__init__("player", None)
self.health = MAX_HP
self.abilities = [Ability(ABIL_JUMP)]
def is_player(self):
""" This actor is controlled by the player. """
return True
def be_hit(self, other, history):
''' Be brutally battered.
Args:
other (Actor): The entity doing the damage.
history (list<str>): The log.
'''
self.health -= 1
if not self.is_alive():
self.die(history)
def die(self, history):
''' Be no longer alive.
Args:
history (list<str>): The log.
'''
self.health = 0
history.append("You die...")
# XXX: would be good to clear the input buffer here, or in things that call this
# once we start properly buffering...
def attempt_move(self, delta, area, history):
''' Attempt to move in the given direction.
If there's an enemy there, hit it.
If the move is successful, leave a trail behind.
Params:
delta (Point): The delta to move from the actor's current position.
area (Area): The area the actor is in.
history (list<str>): The log.
Returns:
Whether the player actually took time. (By moving and/or hitting.)
'''
# grab our previous loc first
cur_loc = area.find_actor(self)
assert cur_loc != None
# check to see whether there's an enemy to murder
did_hit = self.attempt_hit(delta, area, history)
# actually try to move
moved = super().attempt_move(delta, area, history)
if not moved:
return did_hit # still take time if you hit but didn't kill (this probably shouldn't happen?)
# leave a trail
assert cur_loc in area.cells
old_cell = area.cells[cur_loc]
assert old_cell.actor == None
old_cell.actor = Actor('tail', self.cur_color())
return True
def attempt_hit(self, delta, area, history):
''' Attempt to bite whatever's in the given direction.
Params:
delta (Point): The delta to move from the actor's current position.
area (Area): The area the actor is in.
history (list<str>): The log.
Returns:
Whether the player actually hit anything.
'''
cur_loc = area.find_actor(self)
assert cur_loc != None
target = delta + cur_loc
if target not in area.cells:
return False # can't hit outside the map!
target_cell = area.cells[target]
if not target_cell.actor:
return False # nothing to be hit
history.append("You devour {}!".format(target_cell.actor.get_the_name()))
if target_cell.actor._id == 'tail': #XXX: figure out a better way to do this than a literal string comparison
history[-1] += " (Ouch!)"
self.be_hit(self, history)
target_cell.actor = None # XXX: this is killing the actor but will probably need to be generalized at some point
return True
def is_alive(self):
return self.health > 0
def cur_color(self):
""" What color is the player at present?
Returns:
Color: A color corresponding to the player's health.
"""
colors = {
3 : crender.colors.EMERALD,
2 : crender.colors.YELLOW,
1 : crender.colors.RED,
0 : crender.colors.RUST
}
return colors.get(self.health, crender.colors.MAGENTA)
def heal(self, amount):
''' (Partially) restore the player's HP, up to the max.
Args:
amount (int): The # of HP to restore.
Returns:
bool: Whether the healing accomplished anything.
'''
old_health = self.health
self.health = min(self.health + amount, MAX_HP)
return old_health < self.health
def get_abil(self, idstr):
''' Fetch the ability object with the given identifying string.
Args:
idstr (str): The ID of the ability to lookup.
Returns:
Ability: The player's instance of the ability, or None if the player doesn't have one.
'''
# XXX: this could be abstracted further
for abil in self.abilities:
if abil.idstr == idstr:
return abil
return None