def inventory(self, irc, msg, args, user): """ Items in your inventory. """ user_id = None try: user_id = self._get_user_id(irc, msg.prefix) except KeyError: log.error("SpiffyRPG: error getting user id for %s" % msg.prefix) dungeon = self.SpiffyWorld.get_dungeon_by_channel(GAME_CHANNEL) if dungeon is not None: player = dungeon.get_unit_by_user_id(user_id) if player is not None: announcer = PlayerAnnouncer(irc=irc, destination=msg.nick, ircutils=ircutils, ircmsgs=ircmsgs) announcer.inventory(player=player, irc=irc) else: irc.error("Your bags explode, blanketing you in flames!")
def equip(self, irc, msg, args, user, item_name): """ Equips an item from your inventory """ user_id = user.id dungeon = self.SpiffyWorld.get_dungeon_by_channel(GAME_CHANNEL) if dungeon is not None: player = dungeon.get_unit_by_user_id(user_id) if player is not None: equipped_item = player.equip_item_by_name(item_name=item_name) announcer = PlayerAnnouncer(irc=irc, destination=msg.nick, ircutils=ircutils, ircmsgs=ircmsgs) if equipped_item is not None: announcer.item_equip(player=player, item=equipped_item) else: announcer.item_equip_failed(player=player, item_name=equipped_item.name) else: irc.error( "A hulking terror emerges from the darkness and consumes you.") else: irc.error( "You attempt to equip that item, but suddenly burst into flames!")
def use(self, irc, msg, args, user, item_name): """ use <item name> - Use an item in your inventory. """ dungeon_info = self._get_dungeon_and_user_id(irc, msg) if dungeon_info is not None: player = dungeon_info["player"] inventory_item = player.get_item_from_inventory_by_name( item_name=item_name) if inventory_item is not None: item_used_successfully = player.use_item(item=inventory_item) pnick = player.nick player_announcer = PlayerAnnouncer(irc=irc, destination=pnick) if item_used_successfully is not None: player_announcer.use_item(item=inventory_item, irc=irc) else: irc.error( "That item is not usable or has no charges left.") else: irc.error("Item not found!")
def fitems(self, irc, msg, args, unit_name): """ Shows the items of another unit """ dungeon = self.SpiffyWorld.get_dungeon_by_channel(GAME_CHANNEL) if dungeon is not None: unit = dungeon.get_unit_by_name(unit_name) if unit is not None: announcer = PlayerAnnouncer(irc=irc, destination=msg.nick, ircutils=ircutils, ircmsgs=ircmsgs) announcer.inventory(player=unit, irc=irc) else: log.error("SpiffyRPG: could not find dungeon %s" % msg.args[0])
def accept(self, irc, msg, args, user, target_nick): """ accept <nick> - Accepts a challenge from another player """ dungeon_info = self._get_dungeon_and_user_id(irc, msg) if dungeon_info is not None: dungeon = dungeon_info["dungeon"] player = dungeon_info["player"] combatant = dungeon.get_living_unit_by_name(target_nick) if combatant is not None: player.add_battle(combatant=combatant, rounds=3) combatant.add_battle(combatant=player, rounds=3) pnick = player.nick player_announcer = PlayerAnnouncer(irc=irc, destination=pnick) player_announcer.challenge_accepted(combatant=combatant) dungeon.announcer.challenge_accepted(attacker=player, target=combatant) else: irc.error("That target seems to be dead or non-existent.")
def start_round(self, **kwargs): """ 1. Accept battle argument 2. Attacker.attack 3. If hit, add round 4. If miss, target strikes 5. Add round """ player_announcer = None target_announcer = None battle = kwargs["battle"] irc = kwargs["irc"] ircutils = kwargs["ircutils"] ircmsgs = kwargs["ircmsgs"] dungeon = kwargs["dungeon"] if not isinstance(battle, Battle): raise ValueError("battle must be instance of Battle") attacker, target_unit = battle.combatants can_add_round = self.can_add_round(attacker=attacker, target=target_unit) attacker_xp_gained = self.get_xp_for_battle(winner=attacker, loser=target_unit) target_xp_gained = self.get_xp_for_battle(winner=target_unit, loser=attacker) if can_add_round is True: """ Attacker -> attack target unit """ hit_info = attacker.attack(target=target_unit) is_hit = hit_info["is_hit"] item = hit_info["attacker_weapon"] if target_unit.is_player: target_announcer = PlayerAnnouncer(irc=irc, destination=target_unit.nick, ircutils=ircutils, ircmsgs=ircmsgs) target_unit.announcer = target_announcer if attacker.is_player: player_announcer = PlayerAnnouncer(irc=irc, destination=attacker.nick, ircutils=ircutils, ircmsgs=ircmsgs) attacker.announcer = player_announcer self.log.info("{} vs {} !".format(attacker, target_unit)) """ a. Attack lands b. Attack misses (target deals damage instead) c. Draw """ if hit_info["is_draw"]: if player_announcer is not None: player_announcer.draw(item_name=item.name, target_name=target_unit.get_name()) self.log.info("{} vs {} is a DRAW".format(attacker, target_unit)) else: """ Not a draw. Attacker lands hit. Announce damage. Damage is already applied by Unit.attack """ if is_hit: # Your X hits Y for Z damage if player_announcer is not None: player_announcer.damage_dealt(attack_info=hit_info, target=target_unit) # You take X damage from Y's Z if target_announcer is not None: target_announcer.damage_applied(attack_info=hit_info, target=target_unit) battle.add_round(attacker=attacker, target=target_unit, hit_info=hit_info) else: """ Attacker missed. Target unit may now attack the attacker. """ target_hit_info = target_unit.attack(target=attacker) """ This should always be a hit, since the attacker hasn't equipped another item and the original strike was a miss. """ if target_hit_info["is_hit"]: if player_announcer is not None: player_announcer.damage_applied(attack_info=target_hit_info, attacker=target_unit, target=attacker) if target_announcer is not None: target_announcer.damage_dealt(attack_info=target_hit_info, target=attacker) battle.add_round(attacker=target_unit, target=attacker, hit_info=target_hit_info) else: self.log.warn("ANOMALY: %s's -> %s retaliation hit missed!" % (target_unit.get_name(), attacker.get_name())) """ Battle is over if either unit is dead """ if target_unit.is_dead() or attacker.is_dead(): battle.is_complete = True attacker_rounds_won = battle.get_rounds_won(combatant=attacker) target_rounds_won = battle.get_rounds_won(combatant=target_unit) """ Announce victory if the target is dead """ if target_unit.is_dead(): if player_announcer: player_announcer.unit_slain(unit=target_unit) dungeon.announcer.unit_victory(winner=attacker, loser=target_unit, battle=battle, rounds_won=attacker_rounds_won, hit_info=hit_info, xp_gained=attacker_xp_gained) elif attacker.is_dead(): if target_announcer: target_announcer.unit_slain(unit=attacker) dungeon.announcer.unit_victory(winner=target_unit, loser=attacker, battle=battle, rounds_won=target_rounds_won, hit_info=target_hit_info, xp_gained=target_xp_gained) """ If we've reached total rounds, announce winner """ if len(battle.rounds) == battle.total_rounds: attacker_rounds_won = battle.get_rounds_won(combatant=attacker) target_rounds_won = battle.get_rounds_won(combatant=target_unit) if attacker_rounds_won > target_rounds_won: dungeon.announcer.battle_victory(winner=attacker, loser=target_unit, battle=battle, rounds_won=attacker_rounds_won, xp_gained=attacker_xp_gained) elif target_rounds_won > attacker_rounds_won: dungeon.announcer.battle_victory(winner=target_unit, loser=attacker, battle=battle, rounds_won=target_rounds_won, xp_gained=target_xp_gained) else: draw_hit_info = random.shuffle((hit_info, target_hit_info)) winner, loser = random.shuffle((attacker, target_unit)) dungeon.announcer.draw(winner=winner, loser=loser, hit_info=draw_hit_info)
def challenge(self, irc, msg, args, user, unit_name): """ challenge <target> - Challenge target to battle """ """ 1. Get player and unit 2. Get last battle for player and target and make sure both are not None 3. The unit that did not go last is the attacker, or the challenger """ dungeon_info = self._get_dungeon_and_user_id(irc, msg) if dungeon_info is not None: dungeon = dungeon_info["dungeon"] player = dungeon_info["player"] combatant = dungeon.get_living_unit_by_name(unit_name) if combatant is not None: can_battle = player.can_battle_unit(unit=combatant) if can_battle is not True: irc.error("You can't challenge that: %s" % can_battle) return last_battle = player.get_last_incomplete_battle( combatant=combatant) """ If there is an existing battle, they cannot challenge """ if last_battle is not None: irc.error("You're already battling that") return combatant_announcer = PlayerAnnouncer(irc=irc, destination=combatant.nick) player_announcer = PlayerAnnouncer(irc=irc, destination=player.nick) """ New battle if this is a NPC """ if combatant.is_npc: player.add_battle(combatant=combatant, rounds=3) combatant.add_battle(combatant=player, rounds=3) dungeon.announcer.challenge_accepted(attacker=player, target=combatant) player_announcer.challenge_accepted(combatant=combatant) else: """ We don't really need to tell players that their challenge was sent to a NPC since the NPC always accepts. """ player_announcer.challenge_sent(combatant=combatant) """ Combatant is not a player. Let them know they've received a challenge. """ combatant_announcer.challenge_received(combatant=player) """ Schedule challenge forfeit if the challenge was not accepted within the timeout. challenge_timeout = 30 def check_challenge_timeout(): challenge = combatant.get_last_battle_by_combatant(combatant=player) if challenge is not None: seconds_since_challenge = time.time() - challenge.created_at if seconds_since_challenge >= challenge_timeout: player.cancel_challenge(combatant=combatant) schedule.addEvent(check_challenge_timeout, time.time() + challenge_timeout, name="check_challenge_timeout") """ else: irc.error("Invalid target")