def rdl(self, view, pos, line, col=None, attr=None, indent=0): # Maximum number of chars we'll try to print in a line. try: max = view.width - pos[0] # - view.x_acc - pos[0] except: debug.die(view) if len(line) > max: list = re.split("(\W+)", line) string = "" for word in list: if len(word) + len(string) > max: self.rds(view, pos, string, col, attr) max = view.width - view.x_acc pos = (view.x_acc, pos[1] + 1) view.y_acc += 1 string = " " * indent # Skip if: # 1: We're on the start of a line # 2: And the current to-print is nothing # 3: And we're trying to print a space if pos[0] == 0 and string == "" and word.isspace() is True: continue string += word else: string = line self.rds(view, pos, string, col, attr) return len(string)
def update_weapons(self, natural=True, wielded=True): self.weapons = deque() for weapon in self.owner.values("Body", "get_natural_weapons"): if not weapon: debug.die("Component %s tried to add an invalid natural weapon: %s." % (self, weapon)) self.weapons.append(weapon) for weapon in self.owner.values("Manipulation", "get_wielded"): if not weapon: debug.die("Component %s tried to add an invalid equipped weapon: %s." % (self, weapon)) self.weapons.append(weapon)
def get_default_weapon(self, context): """Returns the weapon to default to within a Context.""" weapon = self.get_active_weapon() if not weapon: self.update_weapons() weapon = self.get_active_weapon() if not weapon: debug.die("After update, had no active weapon from list of weapons: %s" % self.weapons) return weapon
def add_contents(self, agent): """Add an Agent to a keyed list in this Container.""" matches = self.contents.get(agent.appearance(), []) # This covers only the case of that exact item already being in container. if agent in matches: debug.die("Tried to add agent %s to container %s." % (agent, self)) matches.append(agent) self.contents[agent.appearance()] = matches return True
def register_component(self, component_class, domain=None): """Initialize an instance of a Component class, register it as the sole member of its domain, and send a "registration" trigger to it.""" if not domain: domain = component_class.get_domain() if domain in self.component_registry: debug.die("Tried to register a component '%s' in the domain '%s', which already has Components %s." % (component_class.__name__, domain, [component.__class__.__name__ for component in self.get_components(domain)])) component = component_class(self) self.append_component(component, domain) component.trigger("registered")
def remove_contents(self, agent): """Remove an Agent from a keyed list in this Container.""" matches = self.contents.get(agent.appearance(), []) # This covers only the case of that exact item already being in container. if agent not in matches: debug.die("Tried to remove agent %s from container %s." % (agent, self)) matches.remove(agent) if matches: self.contents[agent.appearance()] = matches else: del self.contents[agent.appearance()] return True
def wrapper(caller, *args, **kwargs): if isinstance(caller, type): string = "Unimplemented class method %s.%s()" % (caller.__name__, fn.__name__) else: string = "Unimplemented instance method %s.%s()" % (caller.__class__.__name__, fn.__name__) parts = [] if args: parts.append("args: %s" % (args,)) if kwargs: parts.append("kwargs: %s" % kwargs) if parts: string += ".\n" + " " + " \n".join(parts) string += "." debug.die(string)
def _act(self): if not self.turn(): debug.die("%s tried to act when not the acting actor in queue %s." % (self, Queue)) if self.controlled: debug.die("Player-controlled actor %s tried to hit AI code." % self.appearance()) # If we don't have a target, try to find a new one. if not self.pathing.target and not self.pathing.retarget(): # wander aimlessly return self.do(random.choice(dirs)) # Repath if our current target isn't correct if self.pathing.target: if self.pathing.target.coords != self.pathing.destination: self.pathing.destination = self.pathing.target.coords if isinstance(self.pathing.destination, tuple): debug.die([self, self.pathing.destination, self.pathing.target]) self.pathing.repath() # Calculate the distance to the target. self.pathing.distance = self.distance(self.pathing.target) else: if isinstance(self.pathing.destination, tuple): debug.die([self, self.pathing.destination, self.pathing.target]) self.pathing.repath() # TODO: If within attack range, do so. # if self.preferred_reach(self.distance) is True: # return self.do(sub(self.target.coords, self.coords)) # If we've successfully pathed, follow it. if self.pathing.path: debug.log("%s had a path." % self.appearance()) next_step = self.pathing.path.pop() next_dir = next_step - self.coords # # HACK, fixes stuff like teleporting # if dir not in dirs: # self.path.append(pos) # dir = CC if self.map.cell(next_step).can_block(self, next_dir): # TODO: Randomize choice here for alt_dir in arc(next_dir)[1:]: # We already checked the first one alt_next = self.coords + alt_dir # Prefer unoccupied cells, but accept sharing. if not self.map.cell(alt_pos).occupied(): next_dir = alt_dir break elif self.map.cell(alt_pos).blocked(alt_dir) is False: next_dir = alt_dir self.do(next_dir)
def can_reach(self, target, wielded=None, manipulator=None): """Return whether the Agent can reach when manipulating.""" if not wielded and not manipulator: debug.die("Tried to check reach without providing an item or manipulator.") if wielded and not manipulator: manipulator = wielded.call("Wielded", "get_manipulator").get_result() # die("target %s, wielded %s, manip %s" % (target, wielded, manipulator)) min_reach, max_reach = self.get_reach(wielded, manipulator) distance = self.owner.dist(target) # die("dist %s, min %s, max %s" % (distance, min_reach, max_reach)) # Check whether it's too close to reach if distance < min_reach: return False#, "too close" # Check whether it's too far to reach if distance > max_reach: return False#, "too far" return True
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 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