data/observer.py (view raw)
1"""
2Module for all game observers.
3"""
4from . import constants as c
5from .components import attackitems
6from . import setup
7
8class Battle(object):
9 """
10 Observes events of battle and passes info to components.
11 """
12 def __init__(self, level):
13 self.level = level
14 self.info_box = level.info_box
15 self.select_box = level.info_box
16 self.arrow = level.arrow
17 self.player = level.player
18 self.enemies = level.enemy_group
19 self.enemy_list = level.enemy_list
20 self.enemy_index = level.enemy_index
21 self.set_observer_for_enemies()
22 self.event_dict = self.make_event_dict()
23
24 def set_observer_for_enemies(self):
25 for enemy in self.enemies:
26 enemy.observers.append(self)
27
28 def make_event_dict(self):
29 """
30 Make a dictionary of events the Observer can
31 receive.
32 """
33 event_dict = {c.END_BATTLE: self.end_battle,
34 c.SELECT_ACTION: self.select_action,
35 c.SELECT_ITEM: self.select_item,
36 c.SELECT_ENEMY: self.select_enemy,
37 c.SELECT_MAGIC: self.select_magic,
38 c.ENEMY_ATTACK: self.enemy_attack,
39 c.ENEMY_DEAD: self.enemy_dead,
40 c.SWITCH_ENEMY: self.switch_enemy,
41 c.PLAYER_ATTACK: self.player_attack,
42 c.ATTACK_ANIMATION: self.enemy_damaged,
43 c.RUN_AWAY: self.try_to_run_away,
44 c.FLEE: self.flee,
45 c.BATTLE_WON: self.battle_won,
46 c.ENEMY_ATTACK_DAMAGE: self.player_damaged,
47 c.DRINK_HEALING_POTION: self.drink_healing_potion,
48 c.DRINK_ETHER_POTION: self.drink_ether_potion,
49 c.CURE_SPELL: self.cure_spell,
50 c.FIRE_SPELL: self.fire_spell,
51 c.SHOW_EXPERIENCE: self.show_experience,
52 c.LEVEL_UP: self.level_up}
53
54 return event_dict
55
56 def on_notify(self, event):
57 """
58 Notify Observer of event.
59 """
60 if event in self.event_dict:
61 self.event_dict[event]()
62
63 def end_battle(self):
64 """
65 End Battle and flip to previous state.
66 """
67 self.level.end_battle()
68
69 def select_action(self):
70 """
71 Set components to select action.
72 """
73 self.level.state = c.SELECT_ACTION
74 self.arrow.index = 0
75 self.arrow.state = c.SELECT_ACTION
76 self.arrow.image = setup.GFX['smallarrow']
77 self.info_box.state = c.SELECT_ACTION
78
79 def select_enemy(self):
80 self.level.state = c.SELECT_ENEMY
81 self.arrow.index = 0
82 self.arrow.state = c.SELECT_ENEMY
83
84 def select_item(self):
85 self.level.state = c.SELECT_ITEM
86 self.info_box.state = c.SELECT_ITEM
87 self.arrow.become_select_item_state()
88
89 def select_magic(self):
90 self.level.state = c.SELECT_MAGIC
91 self.info_box.state = c.SELECT_MAGIC
92 self.arrow.become_select_magic_state()
93
94 def enemy_attack(self):
95 enemy = self.level.enemy_list[self.level.enemy_index]
96 enemy.enter_enemy_attack_state()
97 self.info_box.state = c.ENEMY_ATTACK
98
99 def switch_enemy(self):
100 """Switch which enemy is attacking player."""
101 if self.level.enemy_index < len(self.level.enemy_list) - 1:
102 self.level.enemy_index += 1
103 self.on_notify(c.ENEMY_ATTACK)
104
105 def player_damaged(self):
106 if self.enemy_index > len(self.enemy_list) - 1:
107 self.enemy_index = 0
108 enemy = self.enemy_list[self.enemy_index]
109 player_damage = enemy.calculate_hit()
110 self.level.damage_points.add(
111 attackitems.HealthPoints(player_damage,
112 self.player.rect.topright))
113 self.info_box.set_player_damage(player_damage)
114 self.info_box.state = c.DISPLAY_ENEMY_ATTACK_DAMAGE
115 self.level.state = c.DISPLAY_ENEMY_ATTACK_DAMAGE
116 self.level.set_timer_to_current_time()
117 self.level.player_damaged(player_damage)
118 if player_damage:
119 self.player.damaged = True
120 self.player.enter_knock_back_state()
121
122 def player_attack(self):
123 enemy_posx = self.arrow.rect.x + 60
124 enemy_posy = self.arrow.rect.y - 20
125 enemy_pos = (enemy_posx, enemy_posy)
126 enemy_to_attack = None
127
128 for enemy in self.enemies:
129 if enemy.rect.topleft == enemy_pos:
130 enemy_to_attack = enemy
131
132 self.player.enter_attack_state(enemy_to_attack)
133 self.arrow.become_invisible_surface()
134
135 def enemy_damaged(self):
136 """
137 Make an attack animation over attacked enemy.
138 """
139 enemy_damage = self.player.calculate_hit()
140 self.level.damage_points.add(
141 attackitems.HealthPoints(enemy_damage,
142 self.player.attacked_enemy.rect.topright))
143
144 self.info_box.set_enemy_damage(enemy_damage)
145 self.info_box.state = c.ENEMY_HIT
146
147 self.arrow.state = c.SELECT_ACTION
148 self.arrow.index = 0
149 self.level.attack_enemy(enemy_damage)
150 self.level.set_timer_to_current_time()
151 self.level.state = c.ENEMY_HIT
152
153
154 def try_to_run_away(self):
155 """
156 Sets a flag in the battle state indicating a desire to run.
157 Allows enemies to get one last hit in.
158 """
159 self.level.run_away = True
160 self.level.state = c.ENEMY_ATTACK
161 self.arrow.become_invisible_surface()
162 self.level.enemy_index = 0
163 self.on_notify(c.ENEMY_ATTACK)
164
165 def flee(self):
166 """
167 Actually run away after enemies get there chance to attack.
168 """
169 self.info_box.state = c.RUN_AWAY
170 self.level.set_timer_to_current_time()
171 self.arrow.become_invisible_surface()
172 self.player.state = c.RUN_AWAY
173
174
175 def battle_won(self):
176 self.info_box.state = c.BATTLE_WON
177 self.level.set_timer_to_current_time()
178 self.player.state = c.VICTORY_DANCE
179
180
181 def drink_healing_potion(self):
182 """
183 Give player a healing potion.
184 """
185 self.level.drink_healing_potion()
186
187 def drink_ether_potion(self):
188 """
189 Give player a ether potion.
190 """
191 self.level.drink_ether()
192
193 def cure_spell(self):
194 """
195 Cast cure spell on player.
196 """
197 self.level.cast_cure()
198
199 def fire_spell(self):
200 """
201 Cast fire spell on all enemies.
202 """
203 self.level.cast_fire_blast()
204
205 def enemy_dead(self):
206 """
207 Eliminate all traces of enemy.
208 """
209 self.player.attacked_enemy = None
210
211 def show_experience(self):
212 """
213 Show the experience the player gained that battle.
214 """
215 self.info_box.state = c.SHOW_EXPERIENCE
216 self.level.set_timer_to_current_time()
217
218 def level_up(self):
219 """
220 Display message that the player leveled up.
221 """
222 self.info_box.reset_level_up_message()
223 self.info_box.state = c.LEVEL_UP
224 self.level.set_timer_to_current_time()
225
226
227
228
229
230
231
232
233