all repos — Legends-RPG @ a5b828ace1209769c68ffed3ad2178da480599a4

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