all repos — Legends-RPG @ 5be4e1fbe674ecf3bf038b8da84f5c49575d4c41

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