all repos — Legends-RPG @ 386aef55098a4fc99b56e6fa1223d98bb02761f1

A fantasy mini-RPG built with Python and Pygame.

data/states/battle.py (view raw)

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