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
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()
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
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())
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
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
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
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
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))
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
def ready(self): self.scroller = self.spawn(Scroller(Log.length() - self.height))