all repos — Legends-RPG @ 2927a342d54f5d95eda1568b0d7d7b31caa4a63b

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