示例#1
0
    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!")
示例#2
0
    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!")
示例#3
0
    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!")
示例#4
0
    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])
示例#5
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.")
示例#6
0
    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)
示例#7
0
    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")