Example #1
0
    def _unequip(self, item):
        if item.is_held() is True:
            locs = item.held[:]
            for loc in locs:
                if loc.owner == self:
                    loc.unhold(item)

        if item.is_readied() is True:
            locs = item.readied[:]
            for loc in locs:
                if loc.owner == self:
                    loc.unready(item)

        if item.is_worn() is True:
            locs = item.worn[:]
            for loc in locs:
                if loc.owner == self:
                    loc.unwear(item)

        self.check_weapons()
        # HACK: Add back to inventory after unequipping.
        self._add(item)
        # HACK: Later, make this a flag
        if self.controlled is True:
            Log.add("%s unequips the %s." % (self.appearance(), item.appearance()))

        return True
Example #2
0
 def before_draw(self, display):
     if Log.length() > self.events:
         max_scroll = max(0, Log.length() - self.height)
         self.scroller.resize(max_scroll)
         if self.autoscroll is True:
             self.scroller.scroll(Log.length() - self.events)
         self.events = Log.length()
Example #3
0
    def _equip(self, item, slots=None, wear=None, weapon=None):
        if self._can_equip_item(item, slots) is False:
            return False

        # If worn T/F is not provided, ask the item whether it's to be worn.
        if wear is None:
            wear = item.can_be_worn()

        # If weapon T/F is not provided, ask the item whether it's a weapon.
        if weapon is None:
            weapon = item.can_be_weapon()

        # Use the item's slots if provided.
        if item.slots is not None:
            slots = item.slots
        # Otherwise use the preferred slot.
        elif slots is None:
            # TODO: Make this check alternate slots, rather than primary_slot.
            slots = [item.preferred_slot()]

        # Get the location objects for the slot.
        locs = []
        for slot in slots:
          locs.append(self.body.locs.get(slot, self.body.primary_slot))

        # Try to wear the item, if possible and if it's not already worn.
        if wear is True and self.worn(item) is False:
            for loc in locs:
                loc.wear(item)

        # Can't wear it? Ready it as a weapon, if applicable and not already readied.
        elif weapon is True and self.readied(item) is False:
            # Hold the weapon, if it needs it.
            if item.requires_empty_location() is True:
                for loc in locs:
                    loc.hold(item)
            # Then ready it.
            for loc in locs:
                loc.ready(item)

        # The only remaining option is to just hold the item.
        elif self.held(item) is False:
            for loc in locs:
                loc.hold(item)

        # Otherwise, we fail.
        else:
            Log.add("%s can't equip the %s right now." % (self.appearance(), item.appearance()))
            return False

        # HACK: Remove the equipped item from inventory.
        self._remove(item)
        self.check_weapons()
        # HACK: Later add a flag.
        if self.controlled is True:
            Log.add("%s equips the %s." % (self.appearance(), item.appearance()))
        return True
Example #4
0
 def knockdown(self):
     if self.can_be_knocked_down() is False:
         return False
     if coin() == SUCC:
         self.change_posture("lying prone")
     else:
         self.change_posture("lying face up")
     # TODO: Improve messaging
     Log.add("%s falls over!" % self.appearance())
Example #5
0
    def process_attack(self, target, weapon, manipulator):
        """Process a single attack."""
        if weapon != self.get_active_weapon():
            debug.die("Tried to attack with inactive weapon %s" % weapon)
        if not manipulator.is_wield(weapon):
            debug.die("Tried to attack with unwielded weapon %s" % weapon)

        wielding_mode = weapon.call("Wielded", "get_wielding_mode").get_result()

        if not wielding_mode:
            debug.die("Weapon %s had no wielding mode" % weapon)

        ctx = CombatContext()
        ctx.add_attack(self.owner, target, weapon, wielding_mode)
        ctx.process_attacks()

        # TODO: Replace with check for whether it's interesting.
        for line in ctx.display():
            Log.add(line)

        return True
Example #6
0
    def hurt(self, attack):
        """Cause the effects decided in prepare_hurt()."""
        if attack.get("knockout") is not None:
            # TODO: Improve messaging
            Log.add("%s is knocked unconscious!" % self.appearance())
            self.knockout()

        if attack.get("knockdown") is not None:
            self.knockdown()

        if attack.get("dropped items") is not None:
            self.drop_all_held()

        if attack.get("stun") is not None and self.get("Status", "Unconscious") is False:
            self.call("Status", "set_status", "Stun", attack["stun"])
            # TODO: Change message.
            Log.add("%s is stunned!" % self.appearance())

        # Handle shock (potentially from multiple sources.)
        if attack.get("shock") is not None:
            shock = self.get("Status", "Shock", 0)
            self.call("Status", "set_status", "Shock", min(4, shock + attack["shock"]))

        # Cause HP loss.
        self.hp_spent += attack["injury"]
        hp = self.HP() # Store HP prior to the attack

        # Decide whether this blow killed you.
        # TODO: Refactor!
        if self.HP() < -self.MaxHP():
            death_checks_made = (min(0,hp) - 1)/self.MaxHP() + 1
            death_checks = (self.HP()-1)/self.MaxHP() + 1
            for death_check in range(-1*(death_checks - death_checks_made)):
                check, margin = self.sc('HT')
                if check < TIE:
                    self.alive = False
Example #7
0
    def process_event(self, event, context):
        """Find the first Command matching an event, instantiate it, and process it."""

        if not self.turn():
            debug.die("Event %s by %s; should be acting: %s; queue: %s" % (event, self.appearance(), Queue.get_acting().appearance(), [a.appearance() for a in Queue.queue]))

        if event not in ["Up", "Down"]:
            debug.log("EVENT: %s" % event)

        for command_class, command_arguments in context.get_commands():
            for command_event in command_class.get_events():
                if event != command_event:
                    continue

                command = command_class(context)
                context.update_arguments(**command_arguments)

                result = self.process_command(command)
                outcome, cause = context.parse_result(result)
                if outcome is True:
                    debug.log("(+): %s" % cause)
                    Log.add("(+): %s" % cause)
                else:
                    debug.log("(-): %s" % cause)
                    Log.add("(-): %s" % cause)

                # TODO: Something else to decide this
                self.end_turn()

                # TODO: Instead return whether the event was consumed.
                return outcome, cause

        if event not in ["Up", "Down"]:
            debug.log("( ): %s" % event)
            Log.add("( ): %s" % event)
        # TODO: Instead return whether the event was consumed.
        return False
Example #8
0
 def do_take_command(self, target):
     """Take command of a target."""
     if self.call("Command", "add_commanded", target).get_result():
         Log.add("%s takes command of %s!" % (self.appearance(), target.appearance()))
         return True
     return False
Example #9
0
 def on_process_death(self):
     """Allow this Actor to respond on its death."""
     # TODO: make this based on whether we can see the dead creature
     # TODO: no messaging here - text generation belongs elsewhere
     Log.add(describe("%s has been slain!" % self.name))
Example #10
0
    def do(self, direction):
        if self.controlled is True and self.can_maneuver() is False:
            if self.alive is False:
                Log.add("%s is dead. Press Ctrl-q to quit the game." % self.appearance())
            else:
                Log.add("%s can't act in its current state." % self.appearance())
            self.end_turn()
            return False

        # Actors that are in our cell.
        # HACK: Need to fix this function to not include self.
        # actors = self.cell().intervening_actors(self.subposition, dir)

        # Within-hex attacks.
        # if actors and self.preferred_reach(0) is True:
        #     for actor in actors:
        #         if self.controlled != actor.controlled:
        #             return self.attack(actor)

        # Can't move if there are intervening actors in that direction.
        # if actors:
        #     return False
        # HACK
        # else:
        #     self.subposition = CC

        # OK, nobody in the way. We're doing something in another hex.
        # Which one?
        pos = self.coords + direction

        # Check for invalid hexes.
        if not self.location.valid(pos):
            if self.controlled:
                Log.add("It would be a long, long way down into that yawning abyss.")
            return False

        cell = self.location.cell(pos)

        # TODO: Make bump attacks cleaner
        if cell and self.has_domain("Combat") and self.could_bump(cell):
            context = Context(agent=self, domains=["Combat"], intent={"attempt" : True},
                                participants=cell.contents)
            for command_class, command_arguments in context.get_commands():
                command = command_class(context)
                context.update_arguments(**command_arguments)
                result = self.process_command(command)
                outcome, cause = context.parse_result(result)
                self.end_turn()
                return outcome

        # The only option left.
        if self.can_move(pos, direction):
            if self.move(pos, direction):
                self.end_turn()
                return True
            if self.controlled:
                Log.add("Bonk! You ran headfirst into a bug. Report it.")
            return False
        else:
            if self.controlled:
                Log.add("Something's blocking the way.")
            return False
Example #11
0
 def ready(self):
     self.scroller = self.spawn(Scroller(Log.length() - self.height))