all repos — Legends-RPG @ c5d70de66c1b6acc4456bef4e66bb278f0375c37

A fantasy mini-RPG built with Python and Pygame.

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