예제 #1
0
    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
예제 #2
0
    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)
예제 #3
0
    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()
예제 #4
0
    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))
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
    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]
예제 #12
0
    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
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    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)
예제 #16
0
    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)
예제 #17
0
    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
예제 #18
0
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
예제 #19
0
 def get(cls, shop):
     """
     Get properties by typeclass's name.
     """
     return WorldData.get_table_data(cls.table_name, shop=shop)
예제 #20
0
 def get_properties(cls, typeclass):
     """
     Get properties by typeclass's name.
     """
     return WorldData.get_table_data(cls.table_name, typeclass=typeclass)
예제 #21
0
    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
예제 #22
0
    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
예제 #23
0
 def get(cls, dialogue_key):
     """
     Get a dialogue by its key.
     """
     return WorldData.get_table_data(cls.table_name, dialogue=dialogue_key)
예제 #24
0
 def get(cls, resource_path):
     """
     Get image's information by resource's path.
     """
     return WorldData.get_table_data(cls.table_name, resource=resource_path)
예제 #25
0
    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)
예제 #26
0
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
예제 #27
0
 def get(cls, provider_key):
     """
     Get a loot list by its key.
     """
     return WorldData.get_table_data(cls.table_name, provider=provider_key)
예제 #28
0
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)