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.SWITCH_ENEMY: self.switch_enemy,
40 c.PLAYER_ATTACK: self.player_attack,
41 c.ATTACK_ANIMATION: self.enemy_damaged,
42 c.RUN_AWAY: self.try_to_run_away,
43 c.FLEE: self.flee,
44 c.BATTLE_WON: self.battle_won,
45 c.ENEMY_ATTACK_DAMAGE: self.player_damaged,
46 c.DRINK_HEALING_POTION: self.drink_healing_potion,
47 c.CURE_SPELL: self.cure_spell,
48 c.FIRE_SPELL: self.fire_spell}
49
50 return event_dict
51
52 def on_notify(self, event):
53 """
54 Notify Observer of event.
55 """
56 if event in self.event_dict:
57 self.event_dict[event]()
58
59 def end_battle(self):
60 """
61 End Battle and flip to previous state.
62 """
63 self.level.end_battle()
64
65 def select_action(self):
66 """
67 Set components to select action.
68 """
69 self.level.state = c.SELECT_ACTION
70 self.arrow.index = 0
71 self.arrow.state = c.SELECT_ACTION
72 self.arrow.image = setup.GFX['smallarrow']
73 self.info_box.state = c.SELECT_ACTION
74
75 def select_enemy(self):
76 self.level.state = c.SELECT_ENEMY
77 self.arrow.index = 0
78 self.arrow.state = c.SELECT_ENEMY
79
80 def select_item(self):
81 self.level.state = c.SELECT_ITEM
82 self.info_box.state = c.SELECT_ITEM
83 self.arrow.become_select_item_state()
84
85 def select_magic(self):
86 self.level.state = c.SELECT_MAGIC
87 self.info_box.state = c.SELECT_MAGIC
88 self.arrow.become_select_magic_state()
89
90 def enemy_attack(self):
91 enemy = self.level.enemy_list[self.level.enemy_index]
92 enemy.enter_enemy_attack_state()
93 self.info_box.state = c.ENEMY_ATTACK
94
95 def switch_enemy(self):
96 """Switch which enemy is attacking player."""
97 if self.level.enemy_index < len(self.level.enemy_list) - 1:
98 self.level.enemy_index += 1
99 self.on_notify(c.ENEMY_ATTACK)
100
101 def player_damaged(self):
102 if self.enemy_index > len(self.enemy_list) - 1:
103 self.enemy_index = 0
104 enemy = self.enemy_list[self.enemy_index]
105 player_damage = enemy.calculate_hit()
106 self.level.damage_points.add(
107 attackitems.HealthPoints(player_damage,
108 self.player.rect.topright))
109 self.info_box.set_player_damage(player_damage)
110 self.info_box.state = c.DISPLAY_ENEMY_ATTACK_DAMAGE
111 self.level.state = c.DISPLAY_ENEMY_ATTACK_DAMAGE
112 self.level.set_timer_to_current_time()
113 self.level.player_damaged(player_damage)
114 if player_damage:
115 self.player.damaged = True
116 self.player.enter_knock_back_state()
117
118 def player_attack(self):
119 enemy_posx = self.arrow.rect.x + 60
120 enemy_posy = self.arrow.rect.y - 20
121 enemy_pos = (enemy_posx, enemy_posy)
122 enemy_to_attack = None
123
124 for enemy in self.enemies:
125 if enemy.rect.topleft == enemy_pos:
126 enemy_to_attack = enemy
127
128 self.player.enter_attack_state(enemy_to_attack)
129 self.arrow.become_invisible_surface()
130
131 def enemy_damaged(self):
132 """
133 Make an attack animation over attacked enemy.
134 """
135 enemy_damage = self.player.calculate_hit()
136 self.level.damage_points.add(
137 attackitems.HealthPoints(enemy_damage,
138 self.player.attacked_enemy.rect.topright))
139
140 self.info_box.set_enemy_damage(enemy_damage)
141 self.info_box.state = c.ENEMY_HIT
142
143 self.arrow.state = c.SELECT_ACTION
144 self.arrow.index = 0
145 self.level.attack_enemy(enemy_damage)
146 self.level.set_timer_to_current_time()
147 self.level.state = c.ENEMY_HIT
148
149
150 def try_to_run_away(self):
151 """
152 Sets a flag in the battle state indicating a desire to run.
153 Allows enemies to get one last hit in.
154 """
155 self.level.run_away = True
156 self.level.state = c.ENEMY_ATTACK
157 self.arrow.become_invisible_surface()
158 self.level.enemy_index = 0
159 self.on_notify(c.ENEMY_ATTACK)
160
161 def flee(self):
162 """
163 Actually run away after enemies get there chance to attack.
164 """
165 self.info_box.state = c.RUN_AWAY
166 self.level.set_timer_to_current_time()
167 self.arrow.become_invisible_surface()
168 self.player.state = c.RUN_AWAY
169
170
171 def battle_won(self):
172 self.info_box.state = c.BATTLE_WON
173 self.level.set_timer_to_current_time()
174 self.player.state = c.VICTORY_DANCE
175
176
177 def drink_healing_potion(self):
178 """
179 Give player a healing potion.
180 """
181 self.player.healing = True
182 self.level.set_timer_to_current_time()
183 self.level.state = c.DRINK_HEALING_POTION
184 self.arrow.become_invisible_surface()
185 self.level.enemy_index = 0
186 self.level.damage_points.add(
187 attackitems.HealthPoints(30,
188 self.player.rect.topright,
189 False))
190 self.level.player_healed(30)
191 self.info_box.state = c.DRINK_HEALING_POTION
192
193 def cure_spell(self):
194 """
195 Cast cure spell on player.
196 """
197 self.level.cast_cure()
198
199
200 def fire_spell(self):
201 """
202 Cast fire spell on all enemies.
203 """
204 self.level.cast_fire_blast()
205
206
207
208
209
210
211