def hide(self, player: IPlayer) -> Optional[bool]: current_accuracy = player.get_attribute_real_value('accuracy') additional = (current_accuracy / 5 * 10) / 100 result = self.game.chose_probability(additional=[additional]) player.set_hidden(result) return
def attack(self, player: IPlayer) -> Optional[bool]: players = self.game.get_remaining_players(player) attack_range = player.get_ranged_attack_area() possible_foes = self.get_attack_possibilities(attack_range, player, players) if len(possible_foes) == 0: self.communicator.informer.no_foes_attack(player) return False enemy_to_attack = self.communicator.questioner.ask_enemy_to_attack(possible_foes) if enemy_to_attack is None: return False self.communicator.informer.force_loading(2) self.communicator.informer.event('attack') dice_result = self.game.roll_the_dice() self.communicator.informer.dice_result(player.name, dice_result, 'attack', self.game.dice_sides) damage = self.calculate_damage(player, enemy_to_attack, dice_result) self.check_player_level_up(player) if damage > 0: enemy_to_attack.suffer_damage(damage) self.communicator.informer.suffer_damage(player, enemy_to_attack, damage) experience = get_configuration(EXPERIENCE_EARNED_ACTION).get('attack', 0) player.earn_xp(experience) self.communicator.informer.player_earned_xp(player_name=player.name, xp=experience) if not enemy_to_attack.is_alive(): experience = get_configuration(EXPERIENCE_EARNED_ACTION).get('kill', 0) player.earn_xp(experience) self.communicator.informer.player_killed_enemy_earned_xp(player_name=player.name, xp=experience) else: self.communicator.informer.missed(player, enemy_to_attack) return
def check_iterated_side_effects(self, player: IPlayer) -> None: iterated_side_effects = [x for x in filter(lambda effect: effect.occurrence == 'iterated', player.side_effects)] for side_effect in iterated_side_effects: self.communicator.informer.event('side-effect') self.communicator.informer.iterated_side_effect_apply(player.name, side_effect) player.compute_iterated_side_effects()
def check_player_level_up(self, player: IPlayer) -> None: if player.experience >= 100: player.experience = player.experience - 100 if isinstance(player, IControlledPlayer): attributes = self.communicator.questioner.ask_attributes_to_improve() else: attributes = improve_attributes_automatically(player.job.get_name(), player.race.get_name()) player.level_up(attributes) self.communicator.informer.player_level_up(player.name, player.level)
def drop(self, player: IPlayer) -> Optional[bool]: selected_item = self.communicator.questioner.select_item(player.bag.items) if selected_item is None: return False confirm = self.communicator.questioner.confirm_item_selection() if confirm: if isinstance(selected_item, IEquipmentItem): player.remove_side_effects(selected_item.side_effects) player.equipment.check_and_remove(selected_item) player.bag.remove_item(selected_item) self.game.game_map.add_item_to_map(player.position, selected_item) return
def equip(self, player: IPlayer) -> Optional[bool]: equipment_item = self.communicator.questioner.display_equipment_choices(player) if equipment_item is None: return False if player.equipment.is_equipped(equipment_item): return False previous_equipment = player.equipment.get_previous_equipped_item(equipment_item.category) if previous_equipment is not None: player.remove_side_effects(previous_equipment.side_effects) player.equipment.equip(equipment_item) player.side_effects.extend(equipment_item.side_effects) return
def check_experience(self, player: IPlayer, successful_skill: bool, killed: bool) -> None: if successful_skill: experience = get_configuration(EXPERIENCE_EARNED_ACTION).get( 'attack', 0) player.earn_xp(experience) self.communicator.informer.player_earned_xp( player_name=player.name, xp=experience) if killed: experience = get_configuration(EXPERIENCE_EARNED_ACTION).get( 'kill', 0) player.earn_xp(experience) self.communicator.informer.player_earned_xp( player_name=player.name, xp=experience)
def move_player(self, player: IPlayer, destination: str) -> None: """ Function to move players along the map, and check if some positions have hidden traps. :param IPlayer player: The player that is currently moving. :param str destination: The destination where player is going. :rtype: None """ traps = self.get_traps_from_position(destination) # TODO - MOVE this validation to orchestrator, so we can use communicator to let players know if len(traps) > 0: for side_effect in traps: player.add_side_effect(side_effect) player.set_position(destination)
def calculate_damage(self, player: IPlayer, foe: IPlayer, dice_result: int) -> int: targeted_defense = 'armour' if player.job.damage_vector == 'strength' else 'magic_resist' damage = 0 if player.job.damage_vector == 'intelligence': damage = (player.get_attribute_real_value(player.job.damage_vector, player.job.attack_type) / 2) + ( dice_result / self.game.dice_sides) * 5 elif player.job.damage_vector == 'strength' and player.job.attack_type == 'ranged': damage = player.get_attribute_real_value(player.job.damage_vector, player.job.attack_type) + player.get_attribute_real_value( 'accuracy') / 2 + ( dice_result / self.game.dice_sides) * 5 else: damage = player.get_attribute_real_value(player.job.damage_vector, player.job.attack_type) + ( dice_result / self.game.dice_sides) * 5 return math.ceil(damage - foe.get_attribute_real_value(targeted_defense))
def no_foes_attack(self, player: IPlayer) -> None: print('There are not any available foes!') print( 'For melee attack, foes must be in the same position as you: {position}' .format(position=player.position)) print('For ranged attack, foes must be within your range of {range}'. format(range=player.get_ranged_attack_area()))
def item(self, player: IPlayer) -> Optional[bool]: using_player = player.name usable_items = player.bag.get_usable_items() selected_item = self.communicator.questioner.select_item(usable_items) if selected_item is None: return False another_players_in_position = self.game.check_another_players_in_position(player) if len(another_players_in_position) > 0: if not self.communicator.questioner.confirm_use_item_on_you(): player = self.communicator.questioner.ask_enemy_to_attack(another_players_in_position) if self.communicator.questioner.confirm_item_selection(): self.communicator.informer.force_loading(2) self.communicator.informer.event('item') target_player = player.name player.use_item(selected_item) self.communicator.informer.use_item(using_player, selected_item.name, target_player) player.bag.remove_item(selected_item) else: return True
def move(self, player: IPlayer) -> Optional[bool]: move_speed = player.get_attribute_real_value('move_speed') possibilities = self.game.game_map.graph.get_available_nodes_in_range(player.position, move_speed) self.communicator.informer.moving_possibilities(player.position, possibilities, self.game.game_map.graph.matrix, self.game.game_map.size) selected_place = self.communicator.questioner.ask_where_to_move(possibilities) self.game.game_map.move_player(player, selected_place) self.communicator.informer.event('move') self.communicator.informer.moved(player.name) return
def suffer_damage(self, attacker: IPlayer, foe: IPlayer, damage: int) -> None: print('\t{name} inflicted a damage of {damage} on {foe_name}'.format( name=attacker.name, damage=damage, foe_name=foe.name)) if not foe.is_alive(): print( colored( '\t{foe_name} it is now dead'.format(foe_name=foe.name), 'red')) else: print('\t{foe_name} now has {life} of life'.format( foe_name=foe.name, life=foe.life))
def calculate_defense( self, foe: IPlayer, ) -> int: # Skills can be magical, based on intelligence, and physical, based on strength # For magical skills, # foe will use magic resist and for physical, armour if self.base_attribute == 'strength': defense_attribute = 'armour' else: defense_attribute = 'magic_resist' return foe.get_defense_value(defense_attribute)
def execute(self, player: IPlayer, foes: List[IPlayer], dice_norm_result: float) -> None: successful_skill = False kill = False player.spend_mana(self.cost) self.communicator.informer.spent_mana(player.name, self.cost, self.name) foe = foes[0] damage = int(self.calculate_damage(player, dice_norm_result)) defense = self.calculate_defense(foe) foe.suffer_damage(damage - defense) self.communicator.informer.suffer_damage(player, foe, damage) player.heal('health_points', damage) self.communicator.informer.heal(player, player, damage) if damage - defense > 0: successful_skill = True if not foe.is_alive(): kill = True self.check_experience(player, successful_skill, kill)
def execute(self, player: IPlayer, foes: List[IPlayer], dice_norm_result: float) -> None: kill = False successful_skill = False player.spend_mana(self.cost) self.communicator.informer.spent_mana(player.name, self.cost, self.name) for foe in foes: if self.kind == 'inflict': damage = self.calculate_damage(player, dice_norm_result) defense = self.calculate_defense(foe) damage = math.ceil(damage - defense) if damage > 0: successful_skill = True foe.suffer_damage(damage) self.communicator.informer.suffer_damage( player, foe, damage) else: self.communicator.informer.missed(player, foe) elif self.kind == 'recover': recover_result = self.calculate_recover( player, dice_norm_result) foe.heal('health_points', recover_result) self.communicator.informer.heal(player, foe, recover_result) for side_effect in self.side_effects: if successful_skill: foe.add_side_effect(side_effect) self.communicator.informer.add_side_effect( foe.name, side_effect) for side_effect in self.punishment_side_effects: player.add_side_effect(side_effect) self.communicator.informer.add_side_effect( player.name, side_effect) if not foe.is_alive(): kill = True print('\n') self.check_experience(player, successful_skill, kill)
def check_side_effect_duration(self, player: IPlayer) -> None: ended_side_effects = player.compute_side_effect_duration() if len(ended_side_effects) > 0: for side_effect in ended_side_effects: self.communicator.informer.side_effect_ended(player.name, side_effect)
def calculate_damage(self, player: IPlayer, dice_norm_result: float) -> float: return self.base + dice_norm_result * player.get_attribute_real_value( self.base_attribute) + player.get_attribute_real_value( self.base_attribute) / 2
def calculate_recover(self, player: IPlayer, dice_norm_result: float) -> int: return math.ceil(self.base + dice_norm_result * player.get_attribute_real_value('intelligence'))
def defend(self, player: IPlayer) -> Optional[bool]: player.set_defense_mode(True) return