def after_data_loaded(self): """ Load goods data. Returns: None """ self.available = False self.shop_key = getattr(self.system, "shop", "") self.goods_key = getattr(self.system, "goods", "") self.goods_level = getattr(self.system, "level", 0) # set goods information self.price = getattr(self.system, "price", 0) self.unit_key = getattr(self.system, "unit", "") self.number = getattr(self.system, "number", 0) self.condition = getattr(self.system, "condition", "") # get price unit information try: # Get record. obj_model_name = TYPECLASS("OBJECT").model_name unit_record = WorldData.get_table_data(obj_model_name, key=self.unit_key) unit_record = unit_record[0] except Exception as e: logger.log_errmsg("Can not find %s's price unit %s." % (self.goods_key, self.unit_key)) return self.unit_name = unit_record.name # load goods try: obj_record = WorldData.get_table_data(obj_model_name, key=self.goods_key) obj_record = obj_record[0] goods_models = TYPECLASS_SET.get_class_modeles( obj_record.typeclass) goods_data = WorldData.get_tables_data(goods_models, key=self.goods_key) except Exception as e: logger.log_errmsg("Can not find goods %s." % self.goods_key) return self.name = goods_data["name"] self.desc = goods_data["desc"] self.icon = goods_data.get("icon", None) self.available = True
def get_object(self, event_key, character, times): """ The character get objects. Args: event_key: (string) event's key. character: (object) relative character. times: (number) event triggered times. """ # get action data records = WorldData.get_table_data(self.model_name, event_key=event_key) # get object list obj_list = [] for record in records: rand = random.random() if rand < record.odds: obj_list.append({ "object": record.object, "number": record.number * times }) objects = character.receive_objects(obj_list, mute=True) accepted = "" for item in objects: if accepted: accepted += ", " accepted += item["name"] + " " + str(item["number"]) if accepted: message = _("Get") + " " + accepted character.msg(message)
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()
def load_system_data(self, base_model, key): """ Get object's system data from database except base data. Args: base_model: (String) base data's table name. key: (String) object's data key. Returns: None """ # Get models. for data_model in self.get_models(): if data_model == base_model: continue # Get data record. try: fields = WorldData.get_fields(data_model) record = WorldData.get_table_data(data_model, key=key) record = record[0] except Exception as e: logger.log_errmsg("Can not find key %s in %s" % (key, data_model)) continue # Set data. for field_name in fields: setattr(self.system, field_name, getattr(record, field_name))
def func(self, event_key, character, obj): """ Start a dialogue. 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) # Get sentence. rand = random.random() # If matches the odds, put the character in combat. # There can be several mods with different odds. for record in records: if rand <= record.odds: # Make dialogue. npc = None if record.npc: npc = utils.search_obj_data_key(record.npc) if npc: npc = npc[0] character.show_dialogue(npc, record.dialogue) return rand -= record.odds
def func(self, event_key, character, obj): """ Start a combat. 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) rand = random.random() # If matches the odds, put the character in combat. # There can be several mods with different odds. for record in records: if rand <= record.odds: # Attack mob. character.attack_temp_target(record.mob, record.level, record.desc) return rand -= record.odds
def get(cls, character): """ Get character's default objects. Args: character: (string) character's key. """ return WorldData.get_table_data(cls.table_name, character=character)
def get_object(self, event_key, character, times): """ The character get objects. Args: event_key: (string) event's key. character: (object) relative character. times: (number) event triggered times. """ # get action data records = WorldData.get_table_data(self.model_name, event_key=event_key) # get object list obj_list = [] msg_template = {} rand = random.random() for record in records: if record.multiple: if rand < record.odds: msg_template[record.object] = record.message obj_list.append({ "object": record.object, "number": record.number * times }) rand = random.random() else: if rand < record.odds: msg_template[record.object] = record.message obj_list.append({ "object": record.object, "number": record.number * times }) break rand -= record.odds objects = character.receive_objects(obj_list, mute=True) message = "" for item in objects: if message: message += ", " template = msg_template[item["key"]] if template: try: message += template % item["number"] except: message += template else: message += _("Get") + " " + item["name"] + " " + str( item["number"]) if message: character.msg(message)
def get_event_data(self, event_key): """ Query all actions of an event. Args: event_key: (string)event's key. """ if not self.model_name: return return WorldData.get_table_data(self.model_name, event_key=event_key)
def get_properties(cls, obj_key, level): """ Get object's properties. Args: obj_key: (string) object's key. level: (number) object's level. """ return WorldData.get_table_data(cls.table_name, object=obj_key, level=level)
def get_quests(self, event_key): """ Get relative quests of this action. Args: event_key: (string) event's key. """ # get action data records = WorldData.get_table_data(self.model_name, event_key=event_key) return [record.quest for record in records]
def calc_combat_rewards(self, winners, losers): """ Called when the character wins the combat. Args: winners: (List) all combat winners. losers: (List) all combat losers. Returns: (dict) reward dict """ rewards = {} for winner in winners: winner_char = self.characters[winner]["char"] exp = 0 loots = [] for loser in losers: loser_char = self.characters[loser]["char"] exp += loser_char.provide_exp(self) obj_list = loser_char.loot_handler.get_obj_list(winner_char) if obj_list: loots.extend(obj_list) obj_list = [] if loots: obj_model_name = TYPECLASS("OBJECT").model_name for obj_info in loots: try: obj_record = WorldData.get_table_data(obj_model_name, key=obj_info["object"]) obj_record = obj_record[0] goods_models = TYPECLASS_SET.get_class_modeles(obj_record.typeclass) goods_data = WorldData.get_tables_data(goods_models, key=obj_info["object"]) obj_list.append({ "object": obj_info["object"], "number": obj_info["number"], "name": goods_data["name"], "icon": goods_data.get("icon", None), "reject": "", }) except Exception as e: logger.log_errmsg("Can not loot object %s." % obj_info["object"]) pass rewards[winner] = { "exp": exp, "loots": obj_list, } return rewards
def func(self, event_key, character, obj): """ Learn a skill. 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) # Learn skills. for record in records: skill_key = record.skill character.learn_skill(skill_key, False, False)
def func(self, event_key, character, obj): """ Close an event. 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) for record in records: # Close event. character.close_event(record.event)
def func(self, event_key, character, obj): """ Send a message to the character. 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) # send messages for record in records: character.msg(record.message)
def func(self, event_key, character, obj): """ Accept a quest. 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) # Accept quests. for record in records: quest_key = record.quest character.quest_handler.accept(quest_key)
def match_condition(self, quest_key): """ Check if the quest matches its condition. Args: quest_key: (string) quest's key Returns: (boolean) result """ # Get quest's record. model_name = TYPECLASS("QUEST").model_name if not model_name: return False try: record = WorldData.get_table_data(model_name, key=quest_key) record = record[0] return STATEMENT_HANDLER.match_condition(record.condition, self.owner, None) except Exception as e: logger.log_errmsg("Can't get quest %s's condition: %s" % (quest_key, e)) return False
def get_object_record(obj_key): """ Query the object's record. Args: obj_key: (string) The key of the object. Returns: The object's data record. """ record = None model_name = TYPECLASS("OBJECT").model_name try: # Get record. record = WorldData.get_table_data(model_name, key=obj_key) record = record[0] except Exception as e: ostring = "Can not get record %s in %s: %s." % (obj_key, model_name, e) print(ostring) print(traceback.print_exc()) return record
def get(cls, shop): """ Get properties by typeclass's name. """ return WorldData.get_table_data(cls.table_name, shop=shop)
def get_properties(cls, typeclass): """ Get properties by typeclass's name. """ return WorldData.get_table_data(cls.table_name, typeclass=typeclass)
def receive_objects(self, obj_list, mute=False): """ Add objects to the inventory. Args: obj_list: (list) a list of object keys and there numbers. list item: {"object": object's key "number": object's number} mute: (boolean) do not send messages to the owner Returns: (list) a list of objects that not have been received and their reasons. [{ "key": key, "name": name, "level": level, "number": number, "icon": icon, "reject": reason, }] """ objects = [] # objects that have been accepted # check what the character has now inventory = {} for item in self.contents: key = item.get_data_key() if key in inventory: # if the character has more than one item of the same kind, # get the smallest stack. if inventory[key].db.number > item.db.number: inventory[key] = item else: inventory[key] = item for obj in obj_list: key = obj["object"] level = obj.get("level") available = obj["number"] name = "" icon = "" number = available accepted = 0 reject = False unique = False if number == 0: # it is an empty object if key in inventory: # already has this object continue object_record = None try: common_model_name = TYPECLASS("COMMON_OBJECT").model_name object_record = WorldData.get_table_data(common_model_name, key=key) object_record = object_record[0] except Exception as e: pass if not object_record: # can not find object's data record continue if object_record.can_remove: # remove this empty object continue # create a new content new_obj = build_object(key, level=level) if not new_obj: reject = _("Can not get %s.") % key else: name = new_obj.get_name() icon = new_obj.icon # move the new object to the character if not new_obj.move_to(self, quiet=True, emit_to_obj=self): new_obj.delete() reject = _("Can not get %s.") % name else: # common number # if already has this kind of object if key in inventory: # add to current object name = inventory[key].name icon = inventory[key].icon unique = inventory[key].unique add = number if add > inventory[key].max_stack - inventory[ key].db.number: add = inventory[key].max_stack - inventory[ key].db.number if add > 0: # increase stack number inventory[key].increase_num(add) number -= add accepted += add # if does not have this kind of object, or stack is full while number > 0: if unique: # can not have more than one unique objects reject = _("Can not get more %s.") % name break # create a new content new_obj = build_object(key, level=level) if not new_obj: reject = _("Can not get %s.") % name break name = new_obj.get_name() icon = new_obj.icon unique = new_obj.unique # move the new object to the character if not new_obj.move_to(self, quiet=True, emit_to_obj=self): new_obj.delete() reject = _("Can not get %s.") % name break # Get the number that actually added. add = number if add > new_obj.max_stack: add = new_obj.max_stack if add <= 0: break new_obj.increase_num(add) number -= add accepted += add objects.append({ "key": key, "name": name, "icon": icon, "number": accepted, "reject": reject, }) if not mute: # Send results to the player. message = {"get_objects": objects} self.msg(message) self.show_inventory() # call quest handler for item in objects: if not item["reject"]: self.quest_handler.at_objective(defines.OBJECTIVE_OBJECT, item["key"], item["number"]) return objects
def return_objectives(self): """ Get the information of all objectives. Set desc to an objective can hide the details of the objective. """ output = [] for ordinal, objective in self.objectives.items(): desc = objective["desc"] if desc: # If an objective has desc, use its desc. output.append({"ordinal": ordinal, "desc": objective["desc"]}) else: # Or make a desc by other data. obj_num = objective["number"] accomplished = self.db.accomplished.get(ordinal, 0) if objective["type"] == defines.OBJECTIVE_TALK: # talking target = _("Talk to") name = DIALOGUE_HANDLER.get_npc_name(objective["object"]) output.append({ "ordinal": ordinal, "target": target, "object": name, "accomplished": accomplished, "total": obj_num, }) elif objective["type"] == defines.OBJECTIVE_OBJECT: # getting target = _("Get") # Get the name of the objective object. object_key = objective["object"] model_name = TYPECLASS("OBJECT").model_name # Get record. try: record = WorldData.get_table_data(model_name, key=object_key) record = record[0] name = record.name except Exception as e: logger.log_err("Can not find the quest object: %s" % object_key) continue output.append({ "ordinal": ordinal, "target": target, "object": name, "accomplished": accomplished, "total": obj_num, }) elif self.objectives[ordinal][ "type"] == defines.OBJECTIVE_KILL: # getting target = _("Kill") # Get the name of the objective character. object_key = self.objectives[ordinal]["object"] model_name = TYPECLASS("OBJECT").model_name # Get record. try: record = WorldData.get_table_data(model_name, key=object_key) record = record[0] name = record.name except Exception as e: logger.log_err("Can not find the quest object: %s" % object_key) continue output.append({ "ordinal": ordinal, "target": target, "object": name, "accomplished": accomplished, "total": obj_num, }) return output
def get(cls, dialogue_key): """ Get a dialogue by its key. """ return WorldData.get_table_data(cls.table_name, dialogue=dialogue_key)
def get(cls, resource_path): """ Get image's information by resource's path. """ return WorldData.get_table_data(cls.table_name, resource=resource_path)
def get_object(self, event_key, character, times): """ The character get objects. Args: event_key: (string) event's key. character: (object) relative character. times: (number) event triggered times. """ # get action data records = WorldData.get_table_data(self.model_name, event_key=event_key) # get object list objects_dict = {} if times <= 100: # Trigger the event only one time. for i in range(times): rand = random.random() for record in records: if record.multiple: if rand < record.odds: if record.object not in objects_dict: objects_dict[record.object] = { "message": record.message, "number": record.number, } else: objects_dict[ record.object]["number"] += record.number rand = random.random() else: if rand < record.odds: if record.object not in objects_dict: objects_dict[record.object] = { "message": record.message, "number": record.number, } else: objects_dict[ record.object]["number"] += record.number break rand -= record.odds else: # If the number of times is too large, simplify the calculation. remain_odds = 1.0 for record in records: if record.multiple: # using normal distribution to simulate binomial distribution mean = record.odds * times standard_deviation = math.sqrt(record.odds * times * (1 - record.odds)) rand = random.normalvariate(mean, standard_deviation) number = round(rand * remain_odds) * record.number if number > 0: if record.object not in objects_dict: objects_dict[record.object] = { "message": record.message, "number": number, } else: objects_dict[record.object]["number"] += number else: odds = record.odds if odds > remain_odds: odds = remain_odds remain_odds -= odds mean = odds * times standard_deviation = math.sqrt(odds * times * (1 - odds)) number = round( random.normalvariate( mean, standard_deviation)) * record.number if number > 0: if record.object not in objects_dict: objects_dict[record.object] = { "message": record.message, "number": number, } else: objects_dict[record.object]["number"] += number obj_list = [{ "object": obj, "number": info["number"] } for obj, info in objects_dict.items()] get_objects = character.receive_objects(obj_list, mute=True) message = "" for item in get_objects: if message: message += ", " template = objects_dict[item["key"]]["message"] if template: try: message += template % item["number"] except: message += template else: message += _("Get") + " " + item["name"] + " " + str( item["number"]) if message: character.msg(message)
def build_object(obj_key, level=None, caller=None, reset_location=True): """ Build objects of a model. Args: obj_key: (string) The key of the object. level: (number) The object's level. caller: (command caller) If provide, running messages will send to the caller. """ # Get object's information record = None typeclass_path = None try: model_name = TYPECLASS("OBJECT").model_name try: # Get record. record = WorldData.get_table_data(model_name, key=obj_key) record = record[0] except Exception as e: ostring = "Can not get record %s in %s: %s." % (obj_key, model_name, e) print(ostring) print(traceback.print_exc()) # get typeclass model typeclass_path = TYPECLASS_SET.get_module(record.typeclass) except Exception as e: ostring = "Can not get typeclass of %s: %s." % (obj_key, e) print(ostring) print(traceback.print_exc()) pass if not record or not typeclass_path: ostring = "Can not find the data of %s." % obj_key print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return # Create object. try: name = getattr(record, "name", "") obj = create.create_object(typeclass_path, name) except Exception as e: ostring = "Can not create obj %s: %s" % (obj_key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return try: # Set data info. obj.set_data_key(record.key, level, reset_location=reset_location) obj.after_creation() except Exception as e: ostring = "Can not set data info to obj %s: %s" % (obj_key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) return return obj
def get(cls, provider_key): """ Get a loot list by its key. """ return WorldData.get_table_data(cls.table_name, provider=provider_key)
def build_unique_objects(objects_data, type_name, caller=None): """ Build all objects in a model. Args: model_name: (string) The name of the data model. caller: (command caller) If provide, running messages will send to the caller. """ # new objects new_obj_keys = set(record.key for record in objects_data) # current objects current_objs = utils.search_obj_unique_type(type_name) # remove objects count_remove = 0 count_update = 0 count_create = 0 current_obj_keys = set() for obj in current_objs: obj_key = obj.get_data_key() if obj_key in current_obj_keys: # This object is duplcated. ostring = "Deleting %s" % obj_key print(ostring) if caller: caller.msg(ostring) # If default home will be removed, set default home to the Limbo. if obj.dbref == settings.DEFAULT_HOME: settings.DEFAULT_HOME = "#2" obj.delete() count_remove += 1 continue if not obj_key in new_obj_keys: # This object should be removed ostring = "Deleting %s" % obj_key print(ostring) if caller: caller.msg(ostring) # If default home will be removed, set default home to the Limbo. if obj.dbref == settings.DEFAULT_HOME: settings.DEFAULT_HOME = "#2" obj.delete() count_remove += 1 continue try: # set data obj.load_data() # put obj to its default location obj.reset_location() except Exception as e: ostring = "%s can not load data:%s" % (obj.dbref, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) current_obj_keys.add(obj_key) # Create new objects. object_model_name = TYPECLASS("OBJECT").model_name for record in objects_data: if not record.key in current_obj_keys: # Create new objects. ostring = "Creating %s." % record.key print(ostring) if caller: caller.msg(ostring) try: object_record = WorldData.get_table_data(object_model_name, key=record.key) object_record = object_record[0] typeclass_path = TYPECLASS_SET.get_module( object_record.typeclass) obj = create.create_object(typeclass_path, object_record.name) count_create += 1 except Exception as e: ostring = "Can not create obj %s: %s" % (record.key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) continue try: obj.set_data_key(record.key) obj.after_creation() utils.set_obj_unique_type(obj, type_name) except Exception as e: ostring = "Can not set data info to obj %s: %s" % (record.key, e) print(ostring) print(traceback.print_exc()) if caller: caller.msg(ostring) continue ostring = "Removed %d object(s). Created %d object(s). Updated %d object(s). Total %d objects.\n"\ % (count_remove, count_create, count_update, len(objects_data)) print(ostring) if caller: caller.msg(ostring)