all repos — Legends-RPG @ 3b7c7c72ba6ca35b3f03d001e978c5539f8a0ebe

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['last state'] = self.name
388        self.game_data['battle counter'] = random.randint(50, 255)
389        self.game_data['battle type'] = None
390        self.state = 'transition out'
391
392    def attack_enemy(self, enemy_damage):
393        enemy = self.player.attacked_enemy
394        enemy.health -= enemy_damage
395        self.set_enemy_indices()
396
397        if enemy:
398            enemy.enter_knock_back_state()
399            if enemy.health <= 0:
400                self.enemy_list.pop(enemy.index)
401                enemy.state = c.FADE_DEATH
402                self.arrow.remove_pos(self.player.attacked_enemy)
403            self.enemy_index = 0
404
405    def set_enemy_indices(self):
406        for i, enemy in enumerate(self.enemy_list):
407            enemy.index = i
408
409    def draw_battle(self, surface):
410        """Draw all elements of battle state"""
411        self.background.draw(surface)
412        self.enemy_group.draw(surface)
413        self.attack_animations.draw(surface)
414        self.sword.draw(surface)
415        surface.blit(self.player.image, self.player.rect)
416        surface.blit(self.info_box.image, self.info_box.rect)
417        surface.blit(self.select_box.image, self.select_box.rect)
418        surface.blit(self.arrow.image, self.arrow.rect)
419        self.player_health_box.draw(surface)
420        self.damage_points.draw(surface)
421        self.draw_transition(surface)
422
423    def draw_transition(self, surface):
424        """
425        Fade in and out of state.
426        """
427        if self.state == 'transition in':
428
429            transition_image = pg.Surface(self.transition_rect.size)
430            transition_image.fill(c.TRANSITION_COLOR)
431            transition_image.set_alpha(self.transition_alpha)
432            surface.blit(transition_image, self.transition_rect)
433            self.transition_alpha -= c.TRANSITION_SPEED 
434            if self.transition_alpha <= 0:
435                self.state = c.SELECT_ACTION
436                self.transition_alpha = 0
437
438        elif self.state == 'transition out':
439            transition_image = pg.Surface(self.transition_rect.size)
440            transition_image.fill(c.TRANSITION_COLOR)
441            transition_image.set_alpha(self.transition_alpha)
442            surface.blit(transition_image, self.transition_rect)
443            self.transition_alpha += c.TRANSITION_SPEED 
444            if self.transition_alpha >= 255:
445                self.done = True
446
447        elif self.state == c.DEATH_FADE:
448            transition_image = pg.Surface(self.transition_rect.size)
449            transition_image.fill(c.TRANSITION_COLOR)
450            transition_image.set_alpha(self.transition_alpha)
451            surface.blit(transition_image, self.transition_rect)
452            self.transition_alpha += c.DEATH_TRANSITION_SPEED
453            if self.transition_alpha >= 255:
454                self.done = True
455                self.next = c.DEATH_SCENE
456
457    def player_damaged(self, damage):
458        self.game_data['player stats']['health']['current'] -= damage
459        if self.game_data['player stats']['health']['current'] <= 0:
460            self.game_data['player stats']['health']['current'] = 0
461            self.state = c.DEATH_FADE
462
463    def player_healed(self, heal, magic_points=0):
464        """
465        Add health from potion to game data.
466        """
467        health = self.game_data['player stats']['health']
468
469        health['current'] += heal
470        if health['current'] > health['maximum']:
471            health['current'] = health['maximum']
472
473        if self.state == c.DRINK_HEALING_POTION:
474            self.game_data['player inventory']['Healing Potion']['quantity'] -= 1
475            if self.game_data['player inventory']['Healing Potion']['quantity'] == 0:
476                del self.game_data['player inventory']['Healing Potion']
477        elif self.state == c.CURE_SPELL:
478            self.game_data['player stats']['magic']['current'] -= magic_points
479
480    def magic_boost(self, magic_points):
481        """
482        Add magic from ether to game data.
483        """
484        magic = self.game_data['player stats']['magic']
485        magic['current'] += magic_points
486        if magic['current'] > magic['maximum']:
487            magic['current'] = magic['maximum']
488
489        self.game_data['player inventory']['Ether Potion']['quantity'] -= 1
490        if not self.game_data['player inventory']['Ether Potion']['quantity']:
491            del self.game_data['player inventory']['Ether Potion']
492
493    def set_timer_to_current_time(self):
494        """Set the timer to the current time."""
495        self.timer = self.current_time
496
497    def cast_fire_blast(self):
498        """
499        Cast fire blast on all enemies.
500        """
501        self.notify(c.FIRE)
502        self.state = self.info_box.state = c.FIRE_SPELL
503        POWER = self.inventory['Fire Blast']['power']
504        MAGIC_POINTS = self.inventory['Fire Blast']['magic points']
505        print MAGIC_POINTS
506        self.game_data['player stats']['magic']['current'] -= MAGIC_POINTS
507        for enemy in self.enemy_list:
508            DAMAGE = random.randint(POWER//2, POWER)
509            self.damage_points.add(
510                attackitems.HealthPoints(DAMAGE, enemy.rect.topright))
511            enemy.health -= DAMAGE
512            posx = enemy.rect.x - 32
513            posy = enemy.rect.y - 64
514            fire_sprite = attack.Fire(posx, posy)
515            self.attack_animations.add(fire_sprite)
516            if enemy.health <= 0:
517                enemy.kill()
518                self.arrow.remove_pos(enemy)
519            else:
520                enemy.enter_knock_back_state()
521        self.enemy_list = [enemy for enemy in self.enemy_list if enemy.health > 0]
522        self.enemy_index = 0
523        self.arrow.index = 0
524        self.arrow.state = 'invisible'
525        self.set_timer_to_current_time()
526
527    def cast_cure(self):
528        """
529        Cast cure spell on player.
530        """
531        self.state = c.CURE_SPELL
532        HEAL_AMOUNT = self.inventory['Cure']['power']
533        MAGIC_POINTS = self.inventory['Cure']['magic points']
534        self.player.healing = True
535        self.set_timer_to_current_time()
536        self.arrow.state = 'invisible'
537        self.enemy_index = 0
538        self.damage_points.add(
539            attackitems.HealthPoints(HEAL_AMOUNT, self.player.rect.topright, False))
540        self.player_healed(HEAL_AMOUNT, MAGIC_POINTS)
541        self.info_box.state = c.DRINK_HEALING_POTION
542        self.notify(c.POWERUP)
543
544    def enter_select_enemy_state(self):
545        """
546        Transition battle into the select enemy state.
547        """
548        self.state = self.arrow.state = c.SELECT_ENEMY
549        self.arrow.index = 0
550
551    def enter_select_item_state(self):
552        """
553        Transition battle into the select item state.
554        """
555        self.state = self.info_box.state = c.SELECT_ITEM
556        self.arrow.become_select_item_state()
557
558    def enter_select_magic_state(self):
559        """
560        Transition battle into the select magic state.
561        """
562        self.state = self.info_box.state = c.SELECT_MAGIC
563        self.arrow.become_select_magic_state()
564
565    def try_to_run_away(self):
566        """
567        Transition battle into the run away state.
568        """
569        self.run_away = True
570        self.arrow.state = 'invisible'
571        self.enemy_index = 0
572        self.enter_enemy_attack_state()
573
574    def enter_enemy_attack_state(self):
575        """
576        Transition battle into the Enemy attack state.
577        """
578        self.state = self.info_box.state = c.ENEMY_ATTACK
579        enemy = self.enemy_list[self.enemy_index]
580        enemy.enter_enemy_attack_state()
581
582    def enter_player_attack_state(self):
583        """
584        Transition battle into the Player attack state.
585        """
586        self.state = self.info_box.state = c.PLAYER_ATTACK
587        enemy_to_attack = self.enemies_to_attack.pop(0)
588        if enemy_to_attack in self.enemy_list:
589            self.player.enter_attack_state(enemy_to_attack)
590        else:
591            if self.enemy_list:
592                self.player.enter_attack_state(self.enemy_list[0])
593            else:
594                self.enter_battle_won_state()
595        self.arrow.state = 'invisible'
596
597    def get_enemy_to_attack(self):
598        """
599        Get enemy for player to attack by arrow position.
600        """
601        enemy_posx = self.arrow.rect.x + 60
602        enemy_posy = self.arrow.rect.y - 20
603        enemy_pos = (enemy_posx, enemy_posy)
604        enemy_to_attack = None
605
606        for enemy in self.enemy_list:
607            if enemy.rect.topleft == enemy_pos:
608                enemy_to_attack = enemy
609
610        return enemy_to_attack
611
612
613    def enter_drink_healing_potion_state(self):
614        """
615        Transition battle into the Drink Healing Potion state.
616        """
617        self.state = self.info_box.state = c.DRINK_HEALING_POTION
618        self.player.healing = True
619        self.set_timer_to_current_time()
620        self.arrow.state = 'invisible'
621        self.enemy_index = 0
622        self.damage_points.add(
623            attackitems.HealthPoints(30,
624                                     self.player.rect.topright,
625                                     False))
626        self.player_healed(30)
627        self.notify(c.POWERUP)
628
629    def enter_drink_ether_potion_state(self):
630        """
631        Transition battle into the Drink Ether Potion state.
632        """
633        self.state = self.info_box.state = c.DRINK_ETHER_POTION
634        self.player.healing = True
635        self.arrow.state = 'invisible'
636        self.enemy_index = 0
637        self.damage_points.add(
638            attackitems.HealthPoints(30,
639                                     self.player.rect.topright,
640                                     False,
641                                     True))
642        self.magic_boost(30)
643        self.set_timer_to_current_time()
644        self.notify(c.POWERUP)
645
646    def enter_select_action_state(self):
647        """
648        Transition battle into the select action state
649        """
650        self.state = self.info_box.state = c.SELECT_ACTION
651        self.arrow.index = 0
652        self.arrow.state = self.state
653
654    def enter_player_damaged_state(self):
655        """
656        Transition battle into the player damaged state.
657        """
658        self.state = self.info_box.state = c.PLAYER_DAMAGED
659        if self.enemy_index > len(self.enemy_list) - 1:
660            self.enemy_index = 0
661        enemy = self.enemy_list[self.enemy_index]
662        player_damage = enemy.calculate_hit(self.inventory['equipped armor'],
663                                            self.inventory)
664        self.damage_points.add(
665            attackitems.HealthPoints(player_damage,
666                                     self.player.rect.topright))
667        self.info_box.set_player_damage(player_damage)
668        self.set_timer_to_current_time()
669        self.player_damaged(player_damage)
670        if player_damage:
671            sfx_num = random.randint(1,3)
672            self.notify('punch{}'.format(sfx_num))
673            self.player.damaged = True
674            self.player.enter_knock_back_state()
675
676    def enter_enemy_damaged_state(self):
677        """
678        Transition battle into the enemy damaged state.
679        """
680        self.state = self.info_box.state = c.ENEMY_DAMAGED
681        enemy_damage = self.player.calculate_hit()
682        self.damage_points.add(
683            attackitems.HealthPoints(enemy_damage,
684                                     self.player.attacked_enemy.rect.topright))
685
686        self.info_box.set_enemy_damage(enemy_damage)
687
688        self.arrow.index = 0
689        self.attack_enemy(enemy_damage)
690        self.set_timer_to_current_time()
691
692    def switch_enemy(self):
693        """
694        Switch which enemy the player is attacking.
695        """
696        if self.enemy_index < len(self.enemy_list) - 1:
697            self.enemy_index += 1
698            self.enter_enemy_attack_state()
699
700    def enter_run_away_state(self):
701        """
702        Transition battle into the run away state.
703        """
704        self.state = self.info_box.state = c.RUN_AWAY
705        self.arrow.state = 'invisible'
706        self.player.state = c.RUN_AWAY
707        self.set_timer_to_current_time()
708        self.notify(c.RUN_AWAY)
709
710    def enter_battle_won_state(self):
711        """
712        Transition battle into the battle won state.
713        """
714        self.notify(c.BATTLE_WON)
715        self.state = self.info_box.state = c.BATTLE_WON
716        self.player.state = c.VICTORY_DANCE
717        self.set_timer_to_current_time()
718
719    def enter_show_gold_state(self):
720        """
721        Transition battle into the show gold state.
722        """
723        self.inventory['GOLD']['quantity'] += self.new_gold
724        self.state = self.info_box.state = c.SHOW_GOLD
725        self.set_timer_to_current_time()
726
727    def enter_show_experience_state(self):
728        """
729        Transition battle into the show experience state.
730        """
731        self.state = self.info_box.state = c.SHOW_EXPERIENCE
732        self.set_timer_to_current_time()
733
734    def enter_level_up_state(self):
735        """
736        Transition battle into the LEVEL UP state.
737        """
738        self.state = self.info_box.state = c.LEVEL_UP
739        self.info_box.reset_level_up_message()
740        self.set_timer_to_current_time()
741
742    def enter_two_actions_per_turn_state(self):
743        self.state = self.info_box.state = c.TWO_ACTIONS
744        self.set_timer_to_current_time()
745
746    def execute_player_actions(self):
747        """
748        Execute the player actions.
749        """
750        if self.player_level < 3:
751            if self.player_actions:
752                enter_state = self.player_action_dict[self.player_actions[0]]
753                enter_state()
754                self.player_actions.pop(0)
755        else:
756            if len(self.player_actions) == 2:
757                enter_state = self.player_action_dict[self.player_actions[0]]
758                enter_state()
759                self.player_actions.pop(0)
760                self.action_selected = False
761            else:
762                if self.action_selected:
763                    self.enter_select_action_state()
764                    self.action_selected = False
765
766
767
768
769
770
771
772
773