all repos — Legends-RPG @ 18c5f497553cc52ee5210424cc6bba07023aed47

A fantasy mini-RPG built with Python and Pygame.

data/states/battle.py (view raw)

  1"""This is the state that handles battles against
  2monsters"""
  3import random, sys
  4from itertools import izip
  5import pygame as pg
  6from .. import tools, battlegui, observer, setup
  7from .. components import person, attack, attackitems
  8from .. import constants as c
  9
 10
 11#Python 2/3 compatibility.
 12if sys.version_info[0] == 2:
 13    range = xrange
 14
 15
 16class Battle(tools._State):
 17    def __init__(self):
 18        super(Battle, self).__init__()
 19        self.name = 'battle'
 20        self.music = setup.MUSIC['high_action']
 21        self.volume = 0.4
 22
 23    def startup(self, current_time, game_data):
 24        """
 25        Initialize state attributes.
 26        """
 27        self.current_time = current_time
 28        self.timer = current_time
 29        self.allow_input = False
 30        self.game_data = game_data
 31        self.inventory = game_data['player inventory']
 32        self.state = 'transition in'
 33        self.next = game_data['last state']
 34        self.run_away = False
 35
 36        self.player = self.make_player()
 37        self.attack_animations = pg.sprite.Group()
 38        self.sword = attackitems.Sword(self.player)
 39        self.enemy_group, self.enemy_pos_list, self.enemy_list = self.make_enemies()
 40        self.experience_points = self.get_experience_points()
 41        self.new_gold = self.get_new_gold()
 42        self.background = self.make_background()
 43        self.info_box = battlegui.InfoBox(game_data, 
 44                                          self.experience_points, 
 45                                          self.new_gold)
 46        self.arrow = battlegui.SelectArrow(self.enemy_pos_list,
 47                                           self.info_box)
 48        self.select_box = battlegui.SelectBox()
 49        self.player_health_box = battlegui.PlayerHealth(self.select_box.rect,
 50                                                        self.game_data)
 51
 52        self.select_action_state_dict = self.make_selection_state_dict()
 53        self.observers = [observer.Battle(self),
 54                          observer.MusicChange()]
 55        self.player.observers.extend(self.observers)
 56        self.observers.append(observer.SoundEffects())
 57        self.damage_points = pg.sprite.Group()
 58        self.player_actions = []
 59        self.player_action_dict = self.make_player_action_dict()
 60        self.player_level = self.game_data['player stats']['Level']
 61        self.enemies_to_attack = []
 62        self.action_selected = False
 63        self.just_leveled_up = False
 64        self.transition_rect = setup.SCREEN.get_rect()
 65        self.transition_alpha = 255
 66        self.temp_magic = self.game_data['player stats']['magic']['current']
 67
 68    def make_player_action_dict(self):
 69        """
 70        Make the dict to execute player actions.
 71        """
 72        action_dict = {c.PLAYER_ATTACK: self.enter_player_attack_state,
 73                       c.CURE_SPELL: self.cast_cure,
 74                       c.FIRE_SPELL: self.cast_fire_blast,
 75                       c.DRINK_HEALING_POTION: self.enter_drink_healing_potion_state,
 76                       c.DRINK_ETHER_POTION: self.enter_drink_ether_potion_state}
 77
 78        return action_dict
 79
 80    def make_enemy_level_dict(self):
 81        new_dict = {c.OVERWORLD: 1,
 82                    c.DUNGEON: 2,
 83                    c.DUNGEON2: 2,
 84                    c.DUNGEON3: 2,
 85                    c.DUNGEON4: 2,
 86                    c.DUNGEON5: 4}
 87
 88        return new_dict
 89
 90    def set_enemy_level(self, enemy_list):
 91        dungeon_level_dict = self.make_enemy_level_dict()
 92
 93        for enemy in enemy_list:
 94            enemy.level = dungeon_level_dict[self.previous]
 95
 96    def get_experience_points(self):
 97        """
 98        Calculate experience points based on number of enemies
 99        and their levels.
100        """
101        experience_total = 0
102
103        for enemy in self.enemy_list:
104            experience_total += (random.randint(5,10))
105
106        return experience_total
107
108    def get_new_gold(self):
109        """
110        Calculate the gold collected at the end of the battle.
111        """
112        gold = 0
113
114        for enemy in self.enemy_list:
115            max_gold = enemy.level * 20
116            gold += (random.randint(1, max_gold))
117
118        return gold
119
120    def make_background(self):
121        """
122        Make the blue/black background.
123        """
124        background = pg.sprite.Sprite()
125        surface = pg.Surface(c.SCREEN_SIZE).convert()
126        surface.fill(c.BLACK_BLUE)
127        background.image = surface
128        background.rect = background.image.get_rect()
129        background_group = pg.sprite.Group(background)
130
131        return background_group
132
133    def make_enemies(self):
134        """
135        Make the enemies for the battle. Return sprite group.
136        """
137        pos_list = []
138
139        for column in range(3):
140            for row in range(3):
141                x = (column * 100) + 100
142                y = (row * 100) + 100
143                pos_list.append([x, y])
144
145        enemy_group = pg.sprite.Group()
146
147        if self.game_data['battle type']:
148            enemy = person.Enemy('evilwizard', 0, 0,
149                                  'down', 'battle resting')
150            enemy_group.add(enemy)
151        else:
152            if self.game_data['start of game']:
153                for enemy in range(3):
154                    enemy_group.add(person.Enemy('devil', 0, 0,
155                                                 'down', 'battle resting'))
156                self.game_data['start of game'] = False
157            else:
158                for enemy in range(random.randint(1, 6)):
159                    enemy_group.add(person.Enemy('devil', 0, 0,
160                                                  'down', 'battle resting'))
161
162        for i, enemy in enumerate(enemy_group):
163            enemy.rect.topleft = pos_list[i]
164            enemy.image = pg.transform.scale2x(enemy.image)
165            enemy.index = i
166            enemy.level = self.make_enemy_level_dict()[self.previous]
167            if enemy.name == 'evilwizard':
168                enemy.health = 100
169            else:
170                enemy.health = enemy.level * 4
171
172        enemy_list = [enemy for enemy in enemy_group]
173
174        return enemy_group, pos_list[0:len(enemy_group)], enemy_list
175
176    def make_player(self):
177        """
178        Make the sprite for the player's character.
179        """
180        player = person.Player('left', self.game_data, 630, 220, 'battle resting', 1)
181        player.image = pg.transform.scale2x(player.image)
182        return player
183
184    def make_selection_state_dict(self):
185        """
186        Make a dictionary of states with arrow coordinates as keys.
187        """
188        pos_list = self.arrow.make_select_action_pos_list()
189        state_list = [self.enter_select_enemy_state, self.enter_select_item_state,
190                      self.enter_select_magic_state, self.try_to_run_away]
191        return dict(izip(pos_list, state_list))
192
193    def update(self, surface, keys, current_time):
194        """
195        Update the battle state.
196        """
197        self.current_time = current_time
198        self.check_input(keys)
199        self.check_timed_events()
200        self.check_if_battle_won()
201        self.enemy_group.update(current_time)
202        self.player.update(keys, current_time)
203        self.attack_animations.update()
204        self.info_box.update()
205        self.arrow.update(keys)
206        self.sword.update(current_time)
207        self.damage_points.update()
208        self.execute_player_actions()
209
210        self.draw_battle(surface)
211
212    def check_input(self, keys):
213        """
214        Check user input to navigate GUI.
215        """
216        if self.allow_input:
217            if keys[pg.K_SPACE]:
218                if self.state == c.SELECT_ACTION:
219                    self.notify(c.CLICK2)
220                    enter_state_function = self.select_action_state_dict[
221                        self.arrow.rect.topleft]
222                    enter_state_function()
223
224                elif self.state == c.SELECT_ENEMY:
225                    self.notify(c.CLICK2)
226                    self.player_actions.append(c.PLAYER_ATTACK)
227                    self.enemies_to_attack.append(self.get_enemy_to_attack())
228                    self.action_selected = True
229
230                elif self.state == c.SELECT_ITEM:
231                    self.notify(c.CLICK2)
232                    if self.arrow.index == (len(self.arrow.pos_list) - 1):
233                        self.enter_select_action_state()
234                    elif self.info_box.item_text_list[self.arrow.index][:14] == 'Healing Potion':
235                        self.player_actions.append(c.DRINK_HEALING_POTION)
236                        self.action_selected = True
237                    elif self.info_box.item_text_list[self.arrow.index][:5] == 'Ether':
238                        self.player_actions.append(c.DRINK_ETHER_POTION)
239                        self.action_selected = True
240                elif self.state == c.SELECT_MAGIC:
241                    self.notify(c.CLICK2)
242                    if self.arrow.index == (len(self.arrow.pos_list) - 1):
243                        self.enter_select_action_state()
244                    elif self.info_box.magic_text_list[self.arrow.index] == 'Cure':
245                        magic_points = self.game_data['player inventory']['Cure']['magic points']
246                        if self.temp_magic >= magic_points:
247                            self.temp_magic -= magic_points
248                            self.player_actions.append(c.CURE_SPELL)
249                            self.action_selected = True
250                    elif self.info_box.magic_text_list[self.arrow.index] == 'Fire Blast':
251                        magic_points = self.game_data['player inventory']['Fire Blast']['magic points']
252                        if self.temp_magic >= magic_points:
253                            self.temp_magic -= magic_points
254                            self.player_actions.append(c.FIRE_SPELL)
255                            self.action_selected = True
256
257            self.allow_input = False
258
259        if keys[pg.K_RETURN] == False and keys[pg.K_SPACE] == False:
260            self.allow_input = True
261
262    def check_timed_events(self):
263        """
264        Check if amount of time has passed for timed events.
265        """
266        timed_states = [c.PLAYER_DAMAGED,
267                        c.ENEMY_DAMAGED,
268                        c.ENEMY_DEAD,
269                        c.DRINK_HEALING_POTION,
270                        c.DRINK_ETHER_POTION]
271        long_delay = timed_states[1:]
272
273        if self.state in long_delay:
274            if (self.current_time - self.timer) > 1000:
275                if self.state == c.ENEMY_DAMAGED:
276                    if self.player_actions:
277                        self.player_action_dict[self.player_actions[0]]()
278                        self.player_actions.pop(0)
279                    else:
280                        if len(self.enemy_list):
281                            self.enter_enemy_attack_state()
282                        else:
283                            self.enter_battle_won_state()
284                elif (self.state == c.DRINK_HEALING_POTION or
285                      self.state == c.CURE_SPELL or
286                      self.state == c.DRINK_ETHER_POTION):
287                    if self.player_actions:
288                        self.player_action_dict[self.player_actions[0]]()
289                        self.player_actions.pop(0)
290                    else:
291                        if len(self.enemy_list):
292                            self.enter_enemy_attack_state()
293                        else:
294                            self.enter_battle_won_state()
295                self.timer = self.current_time
296
297        elif self.state == c.FIRE_SPELL or self.state == c.CURE_SPELL:
298            if (self.current_time - self.timer) > 1500:
299                if self.player_actions:
300                    if not len(self.enemy_list):
301                        self.enter_battle_won_state()
302                    else:
303                        self.player_action_dict[self.player_actions[0]]()
304                        self.player_actions.pop(0)
305                else:
306                    if len(self.enemy_list):
307                        self.enter_enemy_attack_state()
308                    else:
309                        self.enter_battle_won_state()
310                self.timer = self.current_time
311
312        elif self.state == c.RUN_AWAY:
313            if (self.current_time - self.timer) > 1500:
314                self.end_battle()
315
316        elif self.state == c.BATTLE_WON:
317            if (self.current_time - self.timer) > 1800:
318                self.enter_show_gold_state()
319
320        elif self.state == c.SHOW_GOLD:
321            if (self.current_time - self.timer) > 1800:
322                self.enter_show_experience_state()
323
324        elif self.state == c.LEVEL_UP:
325            if (self.current_time - self.timer) > 2200:
326                if self.game_data['player stats']['Level'] == 3:
327                    self.enter_two_actions_per_turn_state()
328                else:
329                    self.end_battle()
330
331        elif self.state == c.TWO_ACTIONS:
332            if (self.current_time - self.timer) > 3000:
333                self.end_battle()
334
335        elif self.state == c.SHOW_EXPERIENCE:
336            if (self.current_time - self.timer) > 2200:
337                player_stats = self.game_data['player stats']
338                player_stats['experience to next level'] -= self.experience_points
339                if player_stats['experience to next level'] <= 0:
340                    extra_experience = player_stats['experience to next level'] * -1
341                    player_stats['Level'] += 1
342                    player_stats['health']['maximum'] += int(player_stats['health']['maximum']*.25)
343                    player_stats['magic']['maximum'] += int(player_stats['magic']['maximum']*.20)
344                    new_experience = int((player_stats['Level'] * 50) * .75)
345                    player_stats['experience to next level'] = new_experience - extra_experience
346                    self.enter_level_up_state()
347                    self.just_leveled_up = True
348                else:
349                    self.end_battle()
350
351        elif self.state == c.PLAYER_DAMAGED:
352            if (self.current_time - self.timer) > 600:
353                if self.enemy_index == (len(self.enemy_list) - 1):
354                    if self.run_away:
355                        self.enter_run_away_state()
356                    else:
357                        self.enter_select_action_state()
358                else:
359                    self.switch_enemy()
360                self.timer = self.current_time
361
362    def check_if_battle_won(self):
363        """
364        Check if state is SELECT_ACTION and there are no enemies left.
365        """
366        if self.state == c.SELECT_ACTION:
367            if len(self.enemy_group) == 0:
368                self.enter_battle_won_state()
369
370    def notify(self, event):
371        """
372        Notify observer of event.
373        """
374        for new_observer in self.observers:
375            new_observer.on_notify(event)
376
377    def end_battle(self):
378        """
379        End battle and flip back to previous state.
380        """
381        if self.game_data['battle type'] == 'evilwizard':
382            self.game_data['crown quest'] = True
383            self.game_data['talked to king'] = True
384        self.game_data['last state'] = self.name
385        self.game_data['battle counter'] = random.randint(50, 255)
386        self.game_data['battle type'] = None
387        self.state = 'transition out'
388
389    def attack_enemy(self, enemy_damage):
390        enemy = self.player.attacked_enemy
391        enemy.health -= enemy_damage
392        self.set_enemy_indices()
393
394        if enemy:
395            enemy.enter_knock_back_state()
396            if enemy.health <= 0:
397                self.enemy_list.pop(enemy.index)
398                enemy.state = c.FADE_DEATH
399                self.arrow.remove_pos(self.player.attacked_enemy)
400            self.enemy_index = 0
401
402    def set_enemy_indices(self):
403        for i, enemy in enumerate(self.enemy_list):
404            enemy.index = i
405
406    def draw_battle(self, surface):
407        """Draw all elements of battle state"""
408        self.background.draw(surface)
409        self.enemy_group.draw(surface)
410        self.attack_animations.draw(surface)
411        self.sword.draw(surface)
412        surface.blit(self.player.image, self.player.rect)
413        surface.blit(self.info_box.image, self.info_box.rect)
414        surface.blit(self.select_box.image, self.select_box.rect)
415        surface.blit(self.arrow.image, self.arrow.rect)
416        self.player_health_box.draw(surface)
417        self.damage_points.draw(surface)
418        self.draw_transition(surface)
419
420    def draw_transition(self, surface):
421        """
422        Fade in and out of state.
423        """
424        if self.state == 'transition in':
425
426            transition_image = pg.Surface(self.transition_rect.size)
427            transition_image.fill(c.TRANSITION_COLOR)
428            transition_image.set_alpha(self.transition_alpha)
429            surface.blit(transition_image, self.transition_rect)
430            self.transition_alpha -= c.TRANSITION_SPEED 
431            if self.transition_alpha <= 0:
432                self.state = c.SELECT_ACTION
433                self.transition_alpha = 0
434
435        elif self.state == 'transition out':
436            transition_image = pg.Surface(self.transition_rect.size)
437            transition_image.fill(c.TRANSITION_COLOR)
438            transition_image.set_alpha(self.transition_alpha)
439            surface.blit(transition_image, self.transition_rect)
440            self.transition_alpha += c.TRANSITION_SPEED 
441            if self.transition_alpha >= 255:
442                self.done = True
443
444        elif self.state == c.DEATH_FADE:
445            transition_image = pg.Surface(self.transition_rect.size)
446            transition_image.fill(c.TRANSITION_COLOR)
447            transition_image.set_alpha(self.transition_alpha)
448            surface.blit(transition_image, self.transition_rect)
449            self.transition_alpha += c.DEATH_TRANSITION_SPEED
450            if self.transition_alpha >= 255:
451                self.done = True
452                self.next = c.DEATH_SCENE
453
454    def player_damaged(self, damage):
455        self.game_data['player stats']['health']['current'] -= damage
456        if self.game_data['player stats']['health']['current'] <= 0:
457            self.game_data['player stats']['health']['current'] = 0
458            self.state = c.DEATH_FADE
459
460    def player_healed(self, heal, magic_points=0):
461        """
462        Add health from potion to game data.
463        """
464        health = self.game_data['player stats']['health']
465
466        health['current'] += heal
467        if health['current'] > health['maximum']:
468            health['current'] = health['maximum']
469
470        if self.state == c.DRINK_HEALING_POTION:
471            self.game_data['player inventory']['Healing Potion']['quantity'] -= 1
472            if self.game_data['player inventory']['Healing Potion']['quantity'] == 0:
473                del self.game_data['player inventory']['Healing Potion']
474        elif self.state == c.CURE_SPELL:
475            self.game_data['player stats']['magic']['current'] -= magic_points
476
477    def magic_boost(self, magic_points):
478        """
479        Add magic from ether to game data.
480        """
481        magic = self.game_data['player stats']['magic']
482        magic['current'] += magic_points
483        self.temp_magic += magic_points
484        if magic['current'] > magic['maximum']:
485            magic['current'] = magic['maximum']
486
487        self.game_data['player inventory']['Ether Potion']['quantity'] -= 1
488        if not self.game_data['player inventory']['Ether Potion']['quantity']:
489            del self.game_data['player inventory']['Ether Potion']
490
491    def set_timer_to_current_time(self):
492        """Set the timer to the current time."""
493        self.timer = self.current_time
494
495    def cast_fire_blast(self):
496        """
497        Cast fire blast on all enemies.
498        """
499        self.notify(c.FIRE)
500        self.state = self.info_box.state = c.FIRE_SPELL
501        POWER = self.inventory['Fire Blast']['power']
502        MAGIC_POINTS = self.inventory['Fire Blast']['magic points']
503        self.game_data['player stats']['magic']['current'] -= MAGIC_POINTS
504        for enemy in self.enemy_list:
505            DAMAGE = random.randint(POWER//2, POWER)
506            self.damage_points.add(
507                attackitems.HealthPoints(DAMAGE, enemy.rect.topright))
508            enemy.health -= DAMAGE
509            posx = enemy.rect.x - 32
510            posy = enemy.rect.y - 64
511            fire_sprite = attack.Fire(posx, posy)
512            self.attack_animations.add(fire_sprite)
513            if enemy.health <= 0:
514                enemy.kill()
515                self.arrow.remove_pos(enemy)
516            else:
517                enemy.enter_knock_back_state()
518        self.enemy_list = [enemy for enemy in self.enemy_list if enemy.health > 0]
519        self.enemy_index = 0
520        self.arrow.index = 0
521        self.arrow.state = 'invisible'
522        self.set_timer_to_current_time()
523
524    def cast_cure(self):
525        """
526        Cast cure spell on player.
527        """
528        self.state = c.CURE_SPELL
529        HEAL_AMOUNT = self.inventory['Cure']['power']
530        MAGIC_POINTS = self.inventory['Cure']['magic points']
531        self.player.healing = True
532        self.set_timer_to_current_time()
533        self.arrow.state = 'invisible'
534        self.enemy_index = 0
535        self.damage_points.add(
536            attackitems.HealthPoints(HEAL_AMOUNT, self.player.rect.topright, False))
537        self.player_healed(HEAL_AMOUNT, MAGIC_POINTS)
538        self.info_box.state = c.DRINK_HEALING_POTION
539        self.notify(c.POWERUP)
540
541    def enter_select_enemy_state(self):
542        """
543        Transition battle into the select enemy state.
544        """
545        self.state = self.arrow.state = c.SELECT_ENEMY
546        self.arrow.index = 0
547
548    def enter_select_item_state(self):
549        """
550        Transition battle into the select item state.
551        """
552        self.state = self.info_box.state = c.SELECT_ITEM
553        self.arrow.become_select_item_state()
554
555    def enter_select_magic_state(self):
556        """
557        Transition battle into the select magic state.
558        """
559        self.state = self.info_box.state = c.SELECT_MAGIC
560        self.arrow.become_select_magic_state()
561
562    def try_to_run_away(self):
563        """
564        Transition battle into the run away state.
565        """
566        self.run_away = True
567        self.arrow.state = 'invisible'
568        self.enemy_index = 0
569        self.enter_enemy_attack_state()
570
571    def enter_enemy_attack_state(self):
572        """
573        Transition battle into the Enemy attack state.
574        """
575        self.state = self.info_box.state = c.ENEMY_ATTACK
576        enemy = self.enemy_list[self.enemy_index]
577        enemy.enter_enemy_attack_state()
578
579    def enter_player_attack_state(self):
580        """
581        Transition battle into the Player attack state.
582        """
583        self.state = self.info_box.state = c.PLAYER_ATTACK
584        enemy_to_attack = self.enemies_to_attack.pop(0)
585        if enemy_to_attack in self.enemy_list:
586            self.player.enter_attack_state(enemy_to_attack)
587        else:
588            if self.enemy_list:
589                self.player.enter_attack_state(self.enemy_list[0])
590            else:
591                self.enter_battle_won_state()
592        self.arrow.state = 'invisible'
593
594    def get_enemy_to_attack(self):
595        """
596        Get enemy for player to attack by arrow position.
597        """
598        enemy_posx = self.arrow.rect.x + 60
599        enemy_posy = self.arrow.rect.y - 20
600        enemy_pos = (enemy_posx, enemy_posy)
601        enemy_to_attack = None
602
603        for enemy in self.enemy_list:
604            if enemy.rect.topleft == enemy_pos:
605                enemy_to_attack = enemy
606
607        return enemy_to_attack
608
609
610    def enter_drink_healing_potion_state(self):
611        """
612        Transition battle into the Drink Healing Potion state.
613        """
614        self.state = self.info_box.state = c.DRINK_HEALING_POTION
615        self.player.healing = True
616        self.set_timer_to_current_time()
617        self.arrow.state = 'invisible'
618        self.enemy_index = 0
619        self.damage_points.add(
620            attackitems.HealthPoints(30,
621                                     self.player.rect.topright,
622                                     False))
623        self.player_healed(30)
624        self.notify(c.POWERUP)
625
626    def enter_drink_ether_potion_state(self):
627        """
628        Transition battle into the Drink Ether Potion state.
629        """
630        self.state = self.info_box.state = c.DRINK_ETHER_POTION
631        self.player.healing = True
632        self.arrow.state = 'invisible'
633        self.enemy_index = 0
634        self.damage_points.add(
635            attackitems.HealthPoints(30,
636                                     self.player.rect.topright,
637                                     False,
638                                     True))
639        self.magic_boost(30)
640        self.set_timer_to_current_time()
641        self.notify(c.POWERUP)
642
643    def enter_select_action_state(self):
644        """
645        Transition battle into the select action state
646        """
647        self.state = self.info_box.state = c.SELECT_ACTION
648        self.arrow.index = 0
649        self.arrow.state = self.state
650
651    def enter_player_damaged_state(self):
652        """
653        Transition battle into the player damaged state.
654        """
655        self.state = self.info_box.state = c.PLAYER_DAMAGED
656        if self.enemy_index > len(self.enemy_list) - 1:
657            self.enemy_index = 0
658        enemy = self.enemy_list[self.enemy_index]
659        player_damage = enemy.calculate_hit(self.inventory['equipped armor'],
660                                            self.inventory)
661        self.damage_points.add(
662            attackitems.HealthPoints(player_damage,
663                                     self.player.rect.topright))
664        self.info_box.set_player_damage(player_damage)
665        self.set_timer_to_current_time()
666        self.player_damaged(player_damage)
667        if player_damage:
668            sfx_num = random.randint(1,3)
669            self.notify('punch{}'.format(sfx_num))
670            self.player.damaged = True
671            self.player.enter_knock_back_state()
672        else:
673            self.notify(c.MISS)
674
675    def enter_enemy_damaged_state(self):
676        """
677        Transition battle into the enemy damaged state.
678        """
679        self.state = self.info_box.state = c.ENEMY_DAMAGED
680        enemy_damage = self.player.calculate_hit()
681        self.damage_points.add(
682            attackitems.HealthPoints(enemy_damage,
683                                     self.player.attacked_enemy.rect.topright))
684
685        self.info_box.set_enemy_damage(enemy_damage)
686
687        self.arrow.index = 0
688        self.attack_enemy(enemy_damage)
689        self.set_timer_to_current_time()
690
691    def switch_enemy(self):
692        """
693        Switch which enemy the player is attacking.
694        """
695        if self.enemy_index < len(self.enemy_list) - 1:
696            self.enemy_index += 1
697            self.enter_enemy_attack_state()
698
699    def enter_run_away_state(self):
700        """
701        Transition battle into the run away state.
702        """
703        self.state = self.info_box.state = c.RUN_AWAY
704        self.arrow.state = 'invisible'
705        self.player.state = c.RUN_AWAY
706        self.set_timer_to_current_time()
707        self.notify(c.RUN_AWAY)
708
709    def enter_battle_won_state(self):
710        """
711        Transition battle into the battle won state.
712        """
713        self.notify(c.BATTLE_WON)
714        self.state = self.info_box.state = c.BATTLE_WON
715        self.player.state = c.VICTORY_DANCE
716        self.set_timer_to_current_time()
717
718    def enter_show_gold_state(self):
719        """
720        Transition battle into the show gold state.
721        """
722        self.inventory['GOLD']['quantity'] += self.new_gold
723        self.state = self.info_box.state = c.SHOW_GOLD
724        self.set_timer_to_current_time()
725
726    def enter_show_experience_state(self):
727        """
728        Transition battle into the show experience state.
729        """
730        self.state = self.info_box.state = c.SHOW_EXPERIENCE
731        self.set_timer_to_current_time()
732
733    def enter_level_up_state(self):
734        """
735        Transition battle into the LEVEL UP state.
736        """
737        self.state = self.info_box.state = c.LEVEL_UP
738        self.info_box.reset_level_up_message()
739        self.set_timer_to_current_time()
740
741    def enter_two_actions_per_turn_state(self):
742        self.state = self.info_box.state = c.TWO_ACTIONS
743        self.set_timer_to_current_time()
744
745    def execute_player_actions(self):
746        """
747        Execute the player actions.
748        """
749        if self.player_level < 3:
750            if self.player_actions:
751                enter_state = self.player_action_dict[self.player_actions[0]]
752                enter_state()
753                self.player_actions.pop(0)
754        else:
755            if len(self.player_actions) == 2:
756                enter_state = self.player_action_dict[self.player_actions[0]]
757                enter_state()
758                self.player_actions.pop(0)
759                self.action_selected = False
760            else:
761                if self.action_selected:
762                    self.enter_select_action_state()
763                    self.action_selected = False
764
765
766
767
768
769
770
771
772