def func(self): "Take off an equipment." caller = self.caller if not self.args: caller.msg({"alert": _("You should take off something.")}) return obj = caller.search_dbref(self.args, location=caller) if not obj: # If the caller does not have this equipment. caller.msg({"alert": _("You don't have this equipment.")}) return try: # Take off the equipment. caller.take_off_equipment(obj) except MudderyError as e: caller.msg({"alert": str(e)}) return except Exception as e: caller.msg({"alert": _("Can not take off this equipment.")}) logger.log_tracemsg("Can not take off %s: %s" % (obj.get_data_key(), e)) return # Send lastest status to the player. message = {"alert": _("Taken off!")} caller.msg(message)
def use_object(self, obj, number=1): """ Use an object. Args: obj: (object) object to use number: (int) number to use Returns: result: (string) the description of the result """ if not obj: return _("Can not find this object.") if obj.db.number < number: return _("Not enough number.") # take effect try: result, used = obj.take_effect(self, number) if used > 0: # remove used object self.remove_object(obj.get_data_key(), used) return result except Exception as e: ostring = "Can not use %s: %s" % (obj.get_data_key(), e) logger.log_tracemsg(ostring) return _("No effect.")
def get_available_commands(self, caller): """ This returns a list of available commands. "args" must be a string without ' and ", usually it is self.dbref. """ commands = [] if self.db.number > 0: if getattr(self, "equipped", False): commands.append({ "name": _("Take Off"), "cmd": "takeoff", "args": self.dbref, }) else: commands.append({ "name": _("Equip"), "cmd": "equip", "args": self.dbref }) # Can not discard when equipped if self.location and self.can_discard: commands.append({ "name": _("Discard"), "cmd": "discard", "args": self.dbref, "confirm": _("Discard this object?"), }) return commands
def func(self): "Continue a dialogue." caller = self.caller if not self.args: caller.msg({"alert": _("You should talk to someone.")}) return npc = None if "npc" in self.args: if self.args["npc"]: # get NPC npc = caller.search_dbref(self.args["npc"], location=caller.location) if not npc: caller.msg({"msg": _("Can not find it.")}) return # Get the current sentence. dialogue = "" sentence = 0 have_current_dlg = False try: dialogue = self.args["dialogue"] sentence = int(self.args["sentence"]) have_current_dlg = True except Exception as e: pass if not have_current_dlg: return caller.continue_dialogue(npc, dialogue, sentence)
def reborn(self): """ Reborn after being killed. """ # Reborn at its home. home = None default_home_key = GAME_SETTINGS.get("default_player_home_key") if default_home_key: rooms = utils.search_obj_data_key(default_home_key) if rooms: home = rooms[0] if not home: rooms = search.search_object(settings.DEFAULT_HOME) if rooms: home = rooms[0] if home: self.move_to(home, quiet=True) # Recover properties. self.recover() self.show_status() if home: self.msg({"msg": _("You are reborn at {C%s{n.") % home.get_name()}) else: self.msg({"msg": _("You are reborn.")})
def func(self): """ Uses the Django admin api. Note that unlogged-in commands have a unique position in that their func() receives a session object instead of a source_object like all other types of logged-in commands (this is because there is no object yet before the player has logged in) """ session = self.caller args = self.args try: playername = args["playername"] password = args["password"] except Exception: string = 'Can not log in.' logger.log_errmsg(string) session.msg({"alert": string}) return # check for too many login errors too quick. if _throttle(session, maxlim=5, timeout=5 * 60, storage=_LATEST_FAILED_LOGINS): # timeout is 5 minutes. session.msg({ "alert": _("{RYou made too many connection attempts. Try again in a few minutes.{n" ) }) return # Guest login if playername.lower() == "guest": enabled, new_player = create_guest_player(session) if new_player: session.msg( {"login": { "name": playername, "dbref": new_player.dbref }}) session.sessionhandler.login(session, new_player) if enabled: return if not password: session.msg({"alert": _("Please input password.")}) return player = connect_normal_player(session, playername, password) if player: # actually do the login. This will call all other hooks: # session.at_login() # player.at_init() # always called when object is loaded from disk # player.at_first_login() # only once, for player-centric setup # player.at_pre_login() # player.at_post_login(session=session) session.msg({"login": {"name": playername, "dbref": player.dbref}}) session.sessionhandler.login(session, player)
def func(self): "Use an object." caller = self.caller if not caller.is_alive(): caller.msg({"alert": _("You are died.")}) return if not self.args: caller.msg({"alert": _("You should use something.")}) return obj = caller.search_dbref(self.args, location=caller) if not obj: # If the caller does not have this object. caller.msg({"alert": _("You don't have this object.")}) return result = "" try: # Use the object and get the result. result = caller.use_object(obj) except Exception as e: ostring = "Can not use %s: %s" % (obj.get_data_key(), e) logger.log_tracemsg(ostring) # Send result to the player. if not result: result = _("No result.") caller.msg({"alert": result})
def func(self): "hook function" session = self.session player = self.account args = self.args current_password = args["current"] new_password = args["new"] if not player.check_password(current_password): session.msg({"alert": _("Incorrect password.")}, session=session) return if len(new_password) < 4: session.msg({"alert": _("Password is too simple.")}, session=session) return player.set_password(new_password) player.save() session.msg({ "alert": _("Password changed."), "pw_changed": True }, session=session)
def func(self): """ Implement the function. """ combat_handler = self.caller.ndb.combat_handler if not combat_handler: # caller is not in combat. return self.obj = self.caller odd = 0.0 if self.args: odd = self.args[0] rand = random.random() if rand >= odd: # escape failed return _("Failed.") # send skill's result to the combat handler manually # before the handler is removed from the character combat_handler.msg_all({ "skill_cast": { "caller": self.caller.get_name(), "target": self.obj.get_name(), "skill": self.key, "main_type": "ESCAPE", "sub_type": "", "cast": _("{R%s{n tried to escape.") % self.caller.get_name(), "result": _("Succeeded!"), } }) combat_handler.escape_combat(self.caller)
def func(self): """ Give up a quest. Returns: None """ caller = self.caller if not caller: return if not self.args: caller.msg({"alert": _("You should give up a quest.")}) return quest_key = self.args try: # Give up the quest. caller.quest_handler.give_up(quest_key) except MudderyError as e: caller.msg({"alert": str(e)}) return except Exception as e: caller.msg({"alert": _("Can not give up this quest.")}) logger.log_tracemsg("Can not give up quest %s: %s" % (quest_key, e)) return # Send lastest status to the player. message = {"alert": _("Given up!")} caller.msg(message)
def func(self): "Open a locked exit." caller = self.caller if not self.args: caller.msg({"alert": _("You should unlock something.")}) return obj = caller.search_dbref(self.args, location=caller.location) if not obj: caller.msg({"alert": _("Can not find this exit.")}) return try: # Unlock the exit. if not caller.unlock_exit(obj): caller.msg({"alert": _("Can not open this exit.") % obj.name}) return except Exception as e: caller.msg({"alert": _("Can not open this exit.")}) logger.log_tracemsg("Can not open exit %s: %s" % (obj.name, e)) return # The exit may have different appearance after unlocking. # Send the lastest appearance to the caller. appearance = obj.get_appearance(caller) caller.msg({"look_obj": appearance})
def sell_to(self, caller): """ Buy this goods. Args: caller: the buyer Returns: """ # check price unit_number = caller.get_object_number(self.unit_key) if unit_number < self.price: caller.msg( {"alert": _("Sorry, %s is not enough.") % self.unit_name}) return # check if can get these objects if not caller.can_get_object(self.goods_key, self.number): caller.msg( {"alert": _("Sorry, you can not take more %s.") % self.name}) return # Reduce price units. if not caller.remove_object(self.unit_key, self.price): caller.msg( {"alert": _("Sorry, %s is not enough.") % self.unit_name}) return # Give goods. obj_list = [{"object": self.goods_key, "number": self.number}] caller.receive_objects(obj_list)
def take_off_position(self, position): """ Take off an object from position. """ if not position in self.db.equipments: raise MudderyError(_("Can not find this equipment.")) if not self.db.equipments[position]: raise MudderyError(_("Can not find this equipment.")) # Set object's attribute 'equipped' to False dbref = self.db.equipments[position] for obj in self.contents: if obj.dbref == dbref: obj.equipped = False find = True self.db.equipments[position] = None # reset character's attributes self.refresh_properties(True) message = { "status": self.return_status(), "equipments": self.return_equipments(), "inventory": self.return_inventory() } self.msg(message)
def func(self): "Use an object." caller = self.caller if not caller.is_alive(): caller.msg({"alert": _("You are died.")}) return if not self.args: caller.msg({"alert": _("You should discard something.")}) return obj = caller.search_dbref(self.args, location=caller) if not obj: # If the caller does not have this object. caller.msg({"alert": _("You don't have this object.")}) return # remove used object try: caller.remove_object(obj.get_data_key(), 1) except Exception as e: caller.msg({"alert": _("Can not discard this object.")}) logger.log_tracemsg("Can not discard object %s: %s" % (obj.get_data_key(), e)) return
def func(self): "create the new character" session = self.session player = self.account args = self.args if not args: session.msg({"alert": _("You should give the character a name.")}) return name = args["name"] if not name: session.msg({"alert": _("Name should not be empty.")}) return # sanity checks if not (0 < len(name) <= 30): # Nickname's length string = "\n\r Name can max be 30 characters or fewer." session.msg({"alert": string}) return # strip excessive spaces in playername nickname = re.sub(r"\s+", " ", name).strip() charmax = settings.MAX_NR_CHARACTERS if settings.MULTISESSION_MODE > 1 else 1 if player.db._playable_characters and len( player.db._playable_characters) >= charmax: session.msg({ "alert": _("You may only create a maximum of %i characters.") % charmax }) return if utils.search_db_data_type("nickname", name, settings.BASE_PLAYER_CHARACTER_TYPECLASS): # check if this name already exists. session.msg({ "alert": _("{RA character named '{r%s{R' already exists.{n") % name }) return try: create_character(player, name) except Exception as e: # We are in the middle between logged in and -not, so we have # to handle tracebacks ourselves at this point. If we don't, # we won't see any errors at all. session.msg( {"alert": _("There was an error creating the Player: %s" % e)}) logger.log_trace() return session.msg({ "char_created": True, "char_all": player.get_all_characters() })
def query_object_properties(typeclass_key, object_key): """ Query all properties of the given object. Args: typeclass_key: (string) typeclass' key. object_key: (string) object' key. """ # Get fields. fields = [] fields.append({ "name": "level", "label": _("Level"), "help_text": _("Properties's level.") }) properties_info = TYPECLASS(typeclass_key).get_properties_info() for key, info in properties_info.items(): if info["mutable"]: continue fields.append({ "name": key, "label": info["name"], "help_text": info["desc"] }) if len(fields) == 1: # No custom properties. table = { "fields": [], "records": [], } return table # Get rows. levels = [] data = {} records = OBJECT_PROPERTIES.get_properties_all_levels(object_key) for record in records: if record.level not in levels: levels.append(record.level) data[record.level] = {"level": record.level} data[record.level][record.property] = record.value rows = [] for level in levels: line = [data[level].get(field["name"], "") for field in fields] rows.append(line) table = { "fields": fields, "records": rows, } return table
def func(self): "delete the character" player = self.account session = self.session args = self.args if not args: self.msg({"alert": _("Please select a character")}) return dbref = args["dbref"] password = args["password"] check = player.check_password(password) if not check: # No password match session.msg({"alert": _("Incorrect password.")}) return # use the playable_characters list to search match = [ char for char in make_iter(player.db._playable_characters) if char.dbref == dbref ] if not match: session.msg({"alert": _("You have no such character to delete.")}) return elif len(match) > 1: session.msg({ "alert": _("Aborting - there are two characters with the same name. Ask an admin to delete the right one." ) }) return else: # one match delobj = match[0] # get new playable characters new_characters = [ char for char in player.db._playable_characters if char != delobj ] # remove object deleted = delobj.delete() if not deleted: session.msg({"alert": _("Can not delete this character.")}) return player.db._playable_characters = new_characters session.msg({ "char_deleted": True, "char_all": player.get_all_characters() })
def cast_skill(self, skill_key, target): """ Cast a skill. Args: skill_key: (string) skill's key. target: (object) skill's target. """ time_now = time.time() if time_now < self.gcd_finish_time: # In GCD. self.msg({"skill_cast": {"cast": _("Global cooling down!")}}) return if skill_key not in self.db.skills: self.msg( {"skill_cast": { "cast": _("You do not have this skill.") }}) return skill = self.db.skills[skill_key] cast_result = skill.cast(target) if not cast_result: return if self.skill_gcd > 0: # set GCD self.gcd_finish_time = time_now + self.skill_gcd skill_cd = { "skill_cd": { "skill": skill_key, # skill's key "cd": skill.cd, # skill's cd "gcd": self.skill_gcd } } skill_result = {"skill_cast": cast_result} self.msg(skill_cd) # send skill result to the player's location if self.is_in_combat(): self.ndb.combat_handler.msg_all(skill_result) else: if self.location: # send skill result to its location self.location.msg_contents(skill_result) else: self.msg(skill_result) return
def localize_model_fields(): """ Localize models field's verbose name and help text. """ for model_name in dir(models): # get model classes model = getattr(models, model_name) if type(model) != type(Model): continue # get model fields for field in model._meta.fields: field.verbose_name = _(field.name, "field_" + model.__name__) field.help_text = _(field.name, "help_" + model.__name__, "")
def func(self): "Do shopping." caller = self.caller if not self.args: caller.msg({"alert": _("You should shopping in someplace.")}) return shop = caller.search_dbref(self.args) if not shop: caller.msg({"alert": _("Can not find this shop.")}) return shop.show_shop(caller)
def get_available_commands(self, caller): """ This returns a list of available commands. "args" must be a string without ' and ", usually it is self.dbref. """ commands = [] if self.db.number > 0: if self.location and self.can_discard: commands.append({ "name": _("Discard"), "cmd": "discard", "args": self.dbref, "confirm": _("Discard this object?"), }) return commands
def die(self, killers): """ This character is killed. Move it to it's home. """ # player's character can always reborn if self.reborn_time < 1: self.reborn_time = 1 super(MudderyPlayerCharacter, self).die(killers) self.msg({"msg": _("You died.")}) if self.reborn_time > 0: self.msg({"msg": _("You will be reborn in {C%(s)s{n seconds.") % {'s': self.reborn_time}})
def func(self): "Talk to an NPC." caller = self.caller if not self.args: caller.msg({"alert": _("You should talk to someone.")}) return npc = caller.search_dbref(self.args, location=caller.location) if not npc: # Can not find the NPC in the caller's location. caller.msg({"alert": _("Can not find the one to talk.")}) return caller.talk_to_npc(npc)
def func(self): "Cast a skill." caller = self.caller args = self.args if not caller.is_alive(): caller.msg({"alert": _("You are died.")}) return if not args: caller.msg({"alert": _("You should select a skill to cast.")}) return # find skill skill_key = None target = None if isinstance(args, str): # If the args is a skill's key. skill_key = args else: # If the args is skill's key and target. if not "skill" in args: caller.msg({"alert": _("You should select a skill to cast.")}) return skill_key = args["skill"] # Check combat if "combat" in args: if args["combat"]: # must be in a combat if not caller.is_in_combat(): return # Get target if "target" in args: target = caller.search_dbref(args["target"]) try: # Prepare to cast this skill. if caller.is_in_combat(): caller.ndb.combat_handler.prepare_skill( skill_key, caller, target) else: caller.cast_skill(skill_key, target) except Exception as e: caller.msg({"alert": _("Can not cast this skill.")}) logger.log_tracemsg("Can not cast skill %s: %s" % (skill_key, e)) return
class ActionRoomInterval(BaseEventAction): """ Triggers an event in a room at interval. """ key = "ACTION_ROOM_INTERVAL" name = _("Room Interval Action", category="event_actions") model_name = "action_room_interval" repeatedly = False def func(self, event_key, character, obj): """ Triggers an event at interval. Args: event_key: (string) event's key. character: (object) relative character. obj: (object) the event object. """ # get action data records = WorldData.get_table_data(self.model_name, event_key=event_key) # Add actions. for record in records: script = create_script(ScriptRoomInterval, key=event_key, interval=record.interval, autostart=False, start_delay=True, persistent=True, obj=character) script.set_action(obj, event_key, record.action, record.offline, record.begin_message, record.end_message) script.start()
class MudderyCommonNPC(TYPECLASS("BASE_NPC")): """ The character not controlled by players. """ typeclass_key = "COMMON_NPC" typeclass_name = _("Common NPC", "typeclasses") model_name = "common_npcs"
def func(self): """ Implement the function. """ if not self.args: return effect = self.args[0] if effect <= 0: return self.obj = self.caller # increase max hp # recover caller's hp increments = {"max_hp": int(effect)} changes = self.caller.change_properties(increments) # increase hp increments_hp = {"hp": changes["max_hp"]} self.caller.change_properties(increments_hp) # send skill result return _("Raised %s's max HP by %d points.") % (self.obj.get_name(), int(changes["max_hp"]))
def func(self): """ Implement the function. """ if not self.args: return effect = self.args[0] if effect <= 0: return if not self.obj: return target_name = self.obj.get_name() # calculate the damage # damage = float(self.caller.attack) / (self.caller.attack + self.obj.defence) * self.caller.attack damage = round(effect) # hurt target increments = {"hp": -damage} changes = self.obj.change_properties(increments) # send skill result return _("Hit %s by %d points.") % (target_name, int(-changes["hp"]))
def turn_in(self, quest_key): """ Turn in a quest. Args: quest_key: (string) quest's key Returns: None """ if quest_key not in self.current_quests: return if not self.current_quests[quest_key].is_accomplished: return # Get quest's name. name = self.current_quests[quest_key].get_name() # Call turn in function in the quest. self.current_quests[quest_key].turn_in() # Delete the quest. self.current_quests[quest_key].delete() del (self.current_quests[quest_key]) self.finished_quests.add(quest_key) self.owner.msg({"msg": _("Turned in quest {C%s{n.") % name}) self.show_quests() self.owner.show_location()
def get_appearance(self, caller): """ This is a convenient hook for a 'look' command to call. """ # Get name and description. if caller.is_exit_unlocked(self.get_data_key()): # If is unlocked, use common appearance. return super(MudderyLockedExit, self).get_appearance(caller) can_unlock = self.can_unlock(caller) if self.auto_unlock and can_unlock: # Automatically unlock the exit when a character looking at it. caller.unlock_exit(self) # If is unlocked, use common appearance. return super(MudderyLockedExit, self).get_appearance(caller) cmds = [] if can_unlock: # show unlock command verb = self.unlock_verb if not verb: verb = _("Unlock") cmds = [{"name": verb, "cmd": "unlock_exit", "args": self.dbref}] info = { "dbref": self.dbref, "name": self.name, "desc": self.locked_desc, "cmds": cmds } return info