def _init_character(self, character): # This initializes handler back-reference and # combat cmdset on a character" character.ndb.combat_handler = self character.cmdset.add("CmdSetCombat.CmdSetCombat") character.ndb.pos = 0 # remove bleeding tick character.stop_bleed() # remove healing tick character.stop_heal() # we essentially delete all status effects on the player at # the start of combat and reinitialize them without an actual # interval, so we force_repeat them manually at the end of each round. # We restore all status effects as well when combat ends, # with their proper intervals and repeats. try: scripts = character.scripts.all() for script in scripts: if script.db.is_status_effect: repeats = script.remaining_repeats() next_repeat = script.time_until_next_repeat() script.stop() if repeats > 1: create_script(script, obj=character, repeats=repeats, interval=COMBAT_ROUND_TIMEOUT) # if there was more than 15 seconds remaining # on the tick, we add it again with a single repeat elif next_repeat > 15: create_script(script, obj=character, repeats=1, interval=COMBAT_ROUND_TIMEOUT) except: pass
def at_add_status_tick(self): """ Combat tick for the turn. Adds any pending status effects. """ for character in self.db.characters.values(): dbref = character.id if self.db.turn_effects[dbref]: for (effect, duration) in self.db.turn_effects[dbref].items(): exist = None repeats = 0 exist = character.scripts.get(effect) if exist: if exist.remaining_repeats(): repeats = exist.remaining_repeats() exist.db.quiet_mode = True exist.stop() if duration: create_script(STATUS_STORAGE.get_effect(effect), obj=character, interval=COMBAT_ROUND_TIMEOUT, repeats=(duration + repeats)) else: create_script(STATUS_STORAGE.get_effect(effect), obj=character, interval=COMBAT_ROUND_TIMEOUT)
def switch_script(self, newclass): scriptobj = self.scriptobj if newclass: if isinstance(newclass, basestring) and newclass == scriptobj.__module__ + '.' + scriptobj.__class__.__name__ or newclass is type(scriptobj): # The class that's already in use was returned. So just show the options again. scriptobj.prompt_switch_out(newscript) scriptobj.prompt_switch_in(scriptobj) else: # We're being replaced by a different class! Create the new script newscript = create_script(newclass, obj=scriptobj.obj, autostart=False) # Copy all our attributes into the new script for attr in scriptobj.get_all_attributes(): if attr.key.startswith('prompt_'): # Skip internal stuff continue newscript.set_attribute(attr.key, attr.value) # Call switching callbacks newscript.prompt_switch_in(scriptobj) scriptobj.prompt_switch_out(newscript) # Stop the old script and start the new one scriptobj.stop() scriptobj = None newscript.start() else: # We're done, and there's nothing to replace us. try: scriptobj.obj.cmdset.delete('PromptState') # The script at_stop will do this again for safety scriptobj.prompt_end() except Exception: raise finally: scriptobj.stop() scriptobj = None
def func(self): character = self.character region = character.get_region() # Ensure the player has permission to leave this area if character.location: if not character.location.access(character, 'leave'): # The access check should display a message return # Ensure the user has enough points to travel wander_cost = region.db.region_wander_cost if wander_cost: for attr, cost in wander_cost.iteritems(): if character.game_attribute(attr) < cost: region.at_wander_incapable(character) self.msg("Navigating this area is beyond your abilities.") return elif character.game_attribute_current(attr) < cost: region.at_wander_insufficient(character) self.msg("You're too tired.") return # Move the character if character.get_room(): prompt_script = create_script('game.gamesrc.latitude.scripts.prompt_wander.PromptWander', obj=character, autostart=False) prompt_script.db.cost = wander_cost prompt_script.db.yes_message = 'You set off to explore your surroundings.' prompt_script.db.no_message = 'You decide to stay where you are.' prompt_script.start() else: message = ['You set off to explore your surroundings.'] if wander_cost: message.extend([character.game_attribute_offset(attr, -cost) for attr, cost in wander_cost.iteritems()]) self.msg(' '.join(message)) region.wander(character)
def _cleanup_character(self, character): # Remove character from handler and clean it # of the back-reference and cmdset" dbref = character.id character.cmdset.delete("CmdSetCombat") if character in self.db.pairs.keys(): del self.db.pairs[character] if dbref in self.db.turn_actions.keys(): del self.db.turn_actions[dbref] if dbref in self.db.turn_combos.keys(): del self.db.turn_combos[dbref] if dbref in self.db.turn_effects.keys(): del self.db.turn_effects[dbref] if dbref in self.db.characters.keys(): del self.db.characters[dbref] del character.ndb.combat_handler if character.ndb.pos: del character.ndb.pos # add bleeding tick if they're bleeding try: for wound in character.db.wounds: if wound.bleed > 0: character.start_bleed() break except: pass # add healing tick character.start_heal() # we unpause all status effects and let them run normally. codedly, # this means removing all of the status effects on the character, # then reinitializing them with the standard interval, # with repeats intact. try: for script in character.scripts.all(): if script.db.is_status_effect: next_repeat_sec = script.time_until_next_repeat() repeats = script.remaining_repeats() script.stop() if repeats > 1 and next_repeat_sec > 20: create_script(script, obj=character, repeats=repeats, interval=30) except: pass
def func(self): character = self.character if character.location: if not character.location.access(character, 'leave'): # The access check should display a message return # Determine the region region = character.get_region() if not region and character.home: region = character.home.get_region() if not region: default_home = ObjectDB.objects.get_id(settings.CHARACTER_DEFAULT_HOME) region = default_home.get_region() if not region: raise Exception('could not find region') # Create the prompt which will verify with the user, and then do the transporting prompt_script = create_script('game.gamesrc.latitude.scripts.prompt_leave.PromptLeave', obj=character, autostart=False) prompt_script.db.destination = region prompt_script.start()
def at_traverse(self, traversing_object, target_location): prompt_script = create_script('game.gamesrc.latitude.scripts.prompt_leave.PromptLeave', obj=traversing_object, autostart=False) prompt_script.db.destination = self.get_region() prompt_script.start()
def cmd_visit(self): character = self.character region = character.get_region() area = character.get_area() areas = [option for option in region.contents if hasattr(option, "can_visit") and option.can_visit(character)] results = search_object(self.args, exact=False, candidates=areas) destination = _AT_SEARCH_RESULT( character, self.args, results, global_search=False, nofound_string="You can't find that area.", multimatch_string="More than one area matches '%s':" % (self.args), ) if not destination: return # The search result hook should have informed the user # Ensure the player has permission to leave this area if character.location: if not character.location.access(character, "leave"): # The access check should display a message return # Ensure the user isn't trying to go where they already are if area == destination: self.msg("{Y[You're already in that area]") return # Ensure the user has enough points to travel (If their maximum is too low to travel here, let them go into negatives.) visit_cost = region.db.region_visit_cost may_go_negative = False if self.capable_cost(visit_cost): if not self.satisfies_cost(visit_cost): region.at_visit_insufficient(character) self.msg("You're too tired.") return else: if not self.maxed_cost(visit_cost): region.at_visit_incapable(character) self.msg( "This region looks very difficult to navigate. If you're going to attempt it, you should rest as much as possible first." ) return may_go_negative = True # Move the character if character.get_room() or may_go_negative: prompt_script = create_script( "game.gamesrc.latitude.scripts.prompt_leave.PromptLeave", obj=character, autostart=False ) if may_go_negative: prompt_script.db.question = "This region seems to be beyond your capabilities. If you try to navigate here, you may be very drained. Are you sure you want to leave the area?" prompt_script.db.destination = destination prompt_script.db.cost = visit_cost prompt_script.db.followers = True prompt_script.db.yes_message = "You head off in search of your destination." prompt_script.db.no_message = "You decide to stay where you are." prompt_script.start() else: message = ["You head off in search of your destination."] if visit_cost: message = [character.game_attribute_offset(attr, -cost) for attr, cost in visit_cost.iteritems()] self.msg(" ".join(message)) character.move_to( destination, redirectable=True, followers=False ) # If you're in the region object, then you shouldn't have followers. If you somehow do, then it's best you lose them now rather than drag them off.