Пример #1
0
    def finish_sentence(self, caller, npc, dialogue, sentence_no):
        """
        A sentence finished, do it's action.
        """
        if not caller:
            return
        
        # get dialogue
        dlg = self.get_dialogue(dialogue)
        if not dlg:
            return

        if sentence_no >= len(dlg["sentences"]):
            return

        sentence = self.get_sentence(dialogue, sentence_no)
        if not sentence:
            return

        # do dialogue's action
        if sentence["action"]:
            SCRIPT_HANDLER.do_action(caller, npc, sentence["action"])

        if sentence["is_last"]:
            # last sentence
            self.finish_dialogue(caller, dialogue)

        if sentence["complete_quest"]:
            caller.quest_handler.complete(sentence["complete_quest"])

        if sentence["provide_quest"]:
            caller.quest_handler.accept(sentence["provide_quest"])
Пример #2
0
    def complete(self):
        """
        Complete a quest, do its action.
        """
        owner = self.db.owner

        # get rewards
        obj_list = self.loot_handler.get_obj_list(owner)
        if obj_list:
            # give objects to winner
            owner.receive_objects(obj_list)

        # do quest's action
        action = getattr(self.dfield, "action", None)
        if action:
            SCRIPT_HANDLER.do_action(owner, None, action)

        # remove objective objects
        obj_list = []
        for ordinal in self.objectives:
            if self.objectives[ordinal]["type"] == defines.OBJECTIVE_OBJECT:
                obj_list.append({"object": self.objectives[ordinal]["object"],
                                 "number": self.objectives[ordinal]["number"]})
        if obj_list:
            owner.remove_objects(obj_list)
Пример #3
0
    def finish_sentence(self, caller, npc, dialogue, sentence):
        """
        A sentence finished, do it's action.
        """
        if not caller:
            return
        
        # get dialogue
        dlg = self.get_dialogue(dialogue)
        if not dlg:
            return

        if sentence >= len(dlg["sentences"]):
            return

        sen = self.get_sentence(dialogue, sentence)
        if not sen:
            return

        # do dialogue's action
        if sen["action"]:
            SCRIPT_HANDLER.do_action(caller, npc, sen["action"])

        if sentence + 1 >= len(dlg["sentences"]):
            # last sentence
            self.finish_dialogue(caller, dialogue)

        if sen["complete_quest"]:
            caller.quest.complete(sen["complete_quest"])

        if sen["provide_quest"]:
            caller.quest.accept(sen["provide_quest"])
Пример #4
0
 def can_unlock(self, caller):
     """
     Unlock an exit.
     """
     # Only can unlock exits which match there conditions.
     return SCRIPT_HANDLER.match_condition(caller, self,
                                           self.unlock_condition)
Пример #5
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_names = OBJECT_KEY_HANDLER.get_models(quest_key)
        if not model_names:
            return False

        for model_name in model_names:
            model_quest = apps.get_model(settings.WORLD_DATA_APP, model_name)

            try:
                record = model_quest.objects.get(key=quest_key)
                return SCRIPT_HANDLER.match_condition(self.owner, None,
                                                      record.condition)
            except ObjectDoesNotExist:
                continue
            except AttributeError:
                continue

        return True
Пример #6
0
    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 = SCRIPT_HANDLER.match_condition(caller, self, self.unlock_condition)

        if can_unlock and self.auto_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 = LS("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
Пример #7
0
    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_info_key()):
            # If is unlocked, use common appearance.
            return super(MudderyLockedExit, self).get_appearance(caller)

        can_unlock = SCRIPT_HANDLER.match_condition(caller, self, self.exit_lock["condition"])

        if can_unlock and self.exit_lock["auto_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.exit_lock["verb"]
            if not verb:
                verb = LS("Unlock")
            cmds = [{"name": verb, "cmd": "unlock_exit", "args": self.dbref}]
        
        info = {"dbref": self.dbref,
                "name": self.name,
                "desc": self.exit_lock["message_lock"],
                "cmds": cmds}
                
        return info
Пример #8
0
    def complete(self):
        """
        Complete a quest, do its action.
        """
        owner = self.db.owner

        # do quest's action
        action = getattr(self.dfield, "action", None)
        if action:
            SCRIPT_HANDLER.do_action(owner, None, action)

        # remove objective objects
        obj_list = []
        for ordinal in self.objectives:
            if self.objectives[ordinal]["type"] == defines.OBJECTIVE_OBJECT:
                obj_list.append({"object": self.objectives[ordinal]["object"],
                                 "number": self.objectives[ordinal]["number"]})
        if obj_list:
            owner.remove_objects(obj_list)
Пример #9
0
    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.
        """
        if not SCRIPT_HANDLER.match_condition(caller, self, self.loot_condition):
            return []

        commands = [{"name": self.loot_verb, "cmd": "loot", "args": self.dbref}]
        return commands
Пример #10
0
    def get_surroundings(self, caller):
        """
        This is a convenient hook for a 'look'
        command to call.
        """
        # get name, description, commands and all objects in it
        info = {
            "exits": [],
            "npcs": [],
            "things": [],
            "players": [],
            "offlines": []
        }

        visible = (cont for cont in self.contents
                   if cont != caller and cont.access(caller, "view"))

        if GAME_SETTINGS.get("solo_mode"):
            visible = (cont for cont in visible if not cont.has_player)

        for cont in visible:
            # only show objects that match the condition
            condition = getattr(cont.dfield, "condition", None)
            if condition:
                if not SCRIPT_HANDLER.match_condition(caller, self, condition):
                    continue

            type = self.get_surrounding_type(cont)
            if type:
                appearance = {}

                if type == "npcs":
                    # add quest status
                    if hasattr(cont, "have_quest"):
                        provide_quest, complete_quest = cont.have_quest(caller)
                        appearance["provide_quest"] = provide_quest
                        appearance["complete_quest"] = complete_quest
                elif type == "exits":
                    # get exits destination
                    if cont.destination:
                        dest = {
                            "name": cont.destination.get_name(),
                            "position": cont.destination.position
                        }
                        appearance["destination"] = dest
                elif type == "offlines":
                    continue

                appearance["dbref"] = cont.dbref
                appearance["name"] = cont.get_name()
                appearance["key"] = cont.get_data_key()

                info[type].append(appearance)

        return info
Пример #11
0
    def dialogue_have_quest(self, caller, npc, dialogue, accomplished_quests):
        """
        Find quests by recursion.
        """
        provide_quest = False
        complete_quest = False

        # check if the dialogue is available
        npc_dlg = self.get_dialogue(dialogue)
        if not npc_dlg:
            return (provide_quest, complete_quest)

        if not SCRIPT_HANDLER.match_condition(caller, npc,
                                              npc_dlg["condition"]):
            return (provide_quest, complete_quest)

        match = True
        for dep in npc_dlg["dependencies"]:
            if not QUEST_DEP_HANDLER.match_dependency(caller, dep["quest"],
                                                      dep["type"]):
                match = False
                break
        if not match:
            return (provide_quest, complete_quest)

        # find quests in its sentences
        for sen in npc_dlg["sentences"]:
            if sen["complete_quest"] in accomplished_quests:
                complete_quest = True
                return (provide_quest, complete_quest)

            if not provide_quest and sen["provide_quest"]:
                quest_key = sen["provide_quest"]
                if caller.quest_handler.can_provide(quest_key):
                    provide_quest = True
                    if not accomplished_quests:
                        return (provide_quest, complete_quest)

        for dlg_key in npc_dlg["nexts"]:
            # get next dialogue
            provide, complete = self.dialogue_have_quest(
                caller, npc, dlg_key, accomplished_quests)

            provide_quest = (provide_quest or provide)
            complete_quest = (complete_quest or complete)

            if complete_quest:
                break

            if not accomplished_quests:
                if provide_quest:
                    break

        return (provide_quest, complete_quest)
Пример #12
0
    def get_npc_sentences(self, caller, npc):
        """
        Get NPC's sentences that can show to the caller.

        Args:
            caller: (object) the character who want to start a talk.
            npc: (object) the NPC that the character want to talk to.

        Returns:
            sentences: (list) a list of available sentences.
        """
        if not caller:
            return

        if not npc:
            return

        sentences = []

        # Get npc's dialogues.
        for dlg_key in npc.dialogues:
            # Get all dialogues.
            npc_dlg = self.get_dialogue(dlg_key)
            if not npc_dlg:
                continue

            # Match conditions.
            if not SCRIPT_HANDLER.match_condition(caller, npc,
                                                  npc_dlg["condition"]):
                continue

            # Match dependeces.
            match = True
            for dep in npc_dlg["dependencies"]:
                if not QUEST_DEP_HANDLER.match_dependency(
                        caller, dep["quest"], dep["type"]):
                    match = False
                    break
            if not match:
                continue

            if npc_dlg["sentences"]:
                # If has sentence, use it.
                sentences.append(npc_dlg["sentences"][0])

        if not sentences:
            # Use default sentences.
            # Default sentences should not have condition and dependencies.
            for dlg_key in npc.default_dialogues:
                npc_dlg = self.get_dialogue(dlg_key)
                if npc_dlg:
                    sentences.append(npc_dlg["sentences"][0])

        return sentences
Пример #13
0
    def get_surroundings(self, caller):
        """
        This is a convenient hook for a 'look'
        command to call.
        """
        # get name, description, commands and all objects in it
        info = {"exits": [],
                "npcs": [],
                "things": [],
                "players": [],
                "offlines": []}

        visible = (cont for cont in self.contents if cont != caller and
                   cont.access(caller, "view"))

        if settings.SOLO_MODE:
            visible = (cont for cont in visible if not cont.has_player)

        for cont in visible:
            # only show objects that match the condition
            condition = getattr(cont.dfield, "condition", None)
            if condition:
                if not SCRIPT_HANDLER.match_condition(caller, self, condition):
                    continue
                        
            type = self.get_surrounding_type(cont)
            if type:
                appearance = {}

                if type == "npcs":
                    # add quest status
                    if hasattr(cont, "have_quest"):
                        provide_quest, complete_quest = cont.have_quest(caller)
                        appearance["provide_quest"] = provide_quest
                        appearance["complete_quest"] = complete_quest
                elif type == "exits":
                    # get exits destination
                    if cont.destination:
                        dest = {"name": cont.destination.get_name(),
                                "position": cont.destination.position}
                        appearance["destination"] = dest
                elif type == "offlines":
                    continue

                appearance["dbref"] = cont.dbref
                appearance["name"] = cont.get_name()
                appearance["key"] = cont.get_info_key()
                
                info[type].append(appearance)

        return info
Пример #14
0
    def dialogue_have_quest(self, caller, npc, dialogue, accomplished_quests):
        """
        Find quests by recursion.
        """
        provide_quest = False
        complete_quest = False

        # check if the dialogue is available
        npc_dlg = self.get_dialogue(dialogue)
        if not npc_dlg:
            return (provide_quest, complete_quest)

        if not SCRIPT_HANDLER.match_condition(caller, npc, npc_dlg["condition"]):
            return (provide_quest, complete_quest)

        match = True
        for dep in npc_dlg["dependencies"]:
            if not QUEST_DEP_HANDLER.match_dependency(caller, dep["quest"], dep["type"]):
                match = False
                break;
        if not match:
            return (provide_quest, complete_quest)

        # find quests in its sentences
        for sen in npc_dlg["sentences"]:
            if sen["complete_quest"] in accomplished_quests:
                complete_quest = True
                return (provide_quest, complete_quest)

            if not provide_quest and sen["provide_quest"]:
                quest_key = sen["provide_quest"]
                if caller.quest.can_provide(quest_key):
                    provide_quest = True
                    if not accomplished_quests:
                        return (provide_quest, complete_quest)

        for dlg_key in npc_dlg["nexts"]:
            # get next dialogue
            provide, complete = self.dialogue_have_quest(caller, npc, dlg_key, accomplished_quests)
                
            provide_quest = (provide_quest or provide)
            complete_quest = (complete_quest or complete)

            if complete_quest:
                break

            if not accomplished_quests:
                if provide_quest:
                    break

        return (provide_quest, complete_quest)
Пример #15
0
    def at_character_kill(self, killers):
        """
        Called when a character kills others.
        This event is set on the character who is killed, and take effect on the killer!
        """
        if defines.EVENT_TRIGGER_KILL in self.events:
            for event in self.events[defines.EVENT_TRIGGER_KILL]:
                # If has kill event.
                for killer in killers:
                    if self.can_bypass(killer):
                        continue

                    if SCRIPT_HANDLER.match_condition(killer, self.owner, event["condition"]):
                        event["function"](event["data"], killer)
Пример #16
0
    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.
        """
        if not SCRIPT_HANDLER.match_condition(caller, self,
                                              self.loot_condition):
            return []

        commands = [{
            "name": self.loot_verb,
            "cmd": "loot",
            "args": self.dbref
        }]
        return commands
Пример #17
0
    def get_next_sentences(self, caller, npc, current_dialogue,
                           current_sentence):
        """
        Get current sentence's next sentences.
        
        Args:
            caller: (object) the character who want to start a talk.
            npc: (object) the NPC that the character want to talk to.
            dialogue: (string) the key of the currrent dialogue.
            sentence: (int) the number of current sentence.

        Returns:
            sentences: (list) a list of available sentences.
        """
        if not caller:
            return

        # Get current dialogue.
        dlg = self.get_dialogue(current_dialogue)
        if not dlg:
            return

        sentences = []

        try:
            # If has next sentence, use next sentence.
            sentences.append(dlg["sentences"][current_sentence + 1])
        except Exception, e:
            # Else get next dialogues.
            for dlg_key in dlg["nexts"]:
                # Get next dialogue.
                next_dlg = self.get_dialogue(dlg_key)
                if not next_dlg:
                    continue

                if not next_dlg["sentences"]:
                    continue

                if not SCRIPT_HANDLER.match_condition(caller, npc,
                                                      next_dlg["condition"]):
                    continue

                for dep in next_dlg["dependencies"]:
                    if not QUEST_DEP_HANDLER.match_dependency(
                            caller, dep["quest"], dep["type"]):
                        continue

                sentences.append(next_dlg["sentences"][0])
Пример #18
0
    def at_character_move_in(self, character):
        """
        Called when a character moves in the event handler's owner, usually a room.
        """
        if not character:
            return

        if self.can_bypass(character):
            return

        if defines.EVENT_TRIGGER_ARRIVE in self.events:
            for event in self.events[defines.EVENT_TRIGGER_ARRIVE]:
                # If has arrive event.
                if SCRIPT_HANDLER.match_condition(character, self.owner, event["condition"]):
                    # If matches the condition.
                    event["function"](event["data"], character)
Пример #19
0
        def can_loot(self, looter, obj):
            """
            help function to decide which objects can be looted.
            """
            rand = random.random()
            if obj["odds"] < rand:
                return False

            if obj["quest"]:
                if not looter.quest.is_not_accomplished(obj["quest"]):
                    return False

            if not SCRIPT_HANDLER.match_condition(looter, self, obj["condition"]):
                return False

            return True
Пример #20
0
    def at_character_kill(self, killers):
        """
        Called when a character kills others.
        This event is set on the character who is killed, and take effect on the killer!
        """
        if defines.EVENT_TRIGGER_KILL in self.events:
            for event in self.events[defines.EVENT_TRIGGER_KILL]:
                # If has kill event.
                for killer in killers:
                    if self.can_bypass(killer):
                        continue

                    if SCRIPT_HANDLER.match_condition(killer, self.owner, event["condition"]):
                        function = self.get_function(event["type"])
                        if function:
                            function(event, killer)
Пример #21
0
        def can_loot(self, looter, obj):
            """
            help function to decide which objects can be looted.
            """
            rand = random.random()
            if obj["odds"] < rand:
                return False

            if obj["quest"]:
                if not looter.quest_handler.is_not_accomplished(obj["quest"]):
                    return False

            if not SCRIPT_HANDLER.match_condition(looter, self.owner,
                                                  obj["condition"]):
                return False

            return True
Пример #22
0
    def get_sentences(self, caller, npc):
        """
        Get NPC's sentences.
        """
        if not caller:
            return

        if not npc:
            return

        sentences = []

        # Get npc's dialogues.
        for dlg_key in npc.dialogues:
            # Get all dialogues.
            npc_dlg = self.get_dialogue(dlg_key)
            if not npc_dlg:
                continue

            # Match conditions.
            if not SCRIPT_HANDLER.match_condition(caller, npc, npc_dlg["condition"]):
                continue

            # Match dependeces.
            match = True
            for dep in npc_dlg["dependencies"]:
                if not QUEST_DEP_HANDLER.match_dependency(caller, dep["quest"], dep["type"]):
                    match = False
                    break
            if not match:
                continue

            if npc_dlg["sentences"]:
                # If has sentence, use it.
                sentences.append(npc_dlg["sentences"][0])

        if not sentences:
            # Use default sentences.
            # Default sentences should not have condition and dependencies.
            for dlg_key in npc.default_dialogues:
                npc_dlg = self.get_dialogue(dlg_key)
                if npc_dlg:
                    sentences.append(npc_dlg["sentences"][0])
            
        return sentences
Пример #23
0
    def at_character_die(self):
        """
        Called when a character is killed.
        """
        owner = self.owner

        if not owner:
            return

        if self.can_bypass(owner):
            return

        if defines.EVENT_TRIGGER_DIE in self.events:
            for event in self.events[defines.EVENT_TRIGGER_DIE]:
                #If has die event.
                if SCRIPT_HANDLER.match_condition(owner, None, event["condition"]):
                    # If matches the condition, run event on the owner.
                    event["function"](event["data"], owner)
Пример #24
0
    def at_character_move_in(self, character):
        """
        Called when a character moves in the event handler's owner, usually a room.
        """
        if not character:
            return

        if self.can_bypass(character):
            return

        if defines.EVENT_TRIGGER_ARRIVE in self.events:
            for event in self.events[defines.EVENT_TRIGGER_ARRIVE]:
                # If has arrive event.
                if SCRIPT_HANDLER.match_condition(character, self.owner, event["condition"]):
                    # If matches the condition.
                    function = self.get_function(event["type"])
                    if function:
                        function(event, character)
Пример #25
0
    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.
        """
        if caller.is_exit_unlocked(self.get_data_key()):
            # If is unlocked, use common commands.
            return super(MudderyLockedExit, self).get_available_commands(caller)

        cmds = []
        can_unlock = SCRIPT_HANDLER.match_condition(caller, self, self.unlock_condition)
        if can_unlock:
            # show unlock command
            verb = self.unlock_verb
            if not verb:
                verb = LS("Unlock")
            cmds = [{"name": verb, "cmd": "unlock", "args": self.dbref}]

        return cmds
Пример #26
0
    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.
        """
        if caller.is_exit_unlocked(self.get_info_key()):
            # If is unlocked, use common commands.
            return super(MudderyLockedExit, self).get_available_commands(caller)

        cmds = []
        can_unlock = SCRIPT_HANDLER.match_condition(caller, self, self.exit_lock["condition"])
        if can_unlock:
            # show unlock command
            verb = self.exit_lock["verb"]
            if not verb:
                verb = LS("Unlock")
            cmds = [{"name": verb, "cmd": "unlock", "args": self.dbref}]

        return cmds
Пример #27
0
    def at_character_die(self):
        """
        Called when a character is killed.
        """
        owner = self.owner

        if not owner:
            return

        if self.can_bypass(owner):
            return

        if defines.EVENT_TRIGGER_DIE in self.events:
            for event in self.events[defines.EVENT_TRIGGER_DIE]:
                #If has die event.
                if SCRIPT_HANDLER.match_condition(owner, None, event["condition"]):
                    # If matches the condition, run event on the owner.
                    function = self.get_function(event["type"])
                    if function:
                        function(event, self)
Пример #28
0
    def at_character_traverse(self, character):
        """
        Called before a character traverses an exit.
        If returns true, the character can pass the exit, else the character can not pass the exit.
        """
        if not character:
            return True

        if self.can_bypass(character):
            return True

        triggered = False
        if defines.EVENT_TRIGGER_TRAVERSE in self.events:
            for event in self.events[defines.EVENT_TRIGGER_TRAVERSE]:
                # If has traverse event.
                if SCRIPT_HANDLER.match_condition(character, self.owner, event["condition"]):
                    # If matches the condition.
                    triggered = True
                    event["function"](event["data"], character)

        return not triggered
Пример #29
0
    def at_character_traverse(self, character):
        """
        Called before a character traverses an exit.
        If returns true, the character can pass the exit, else the character can not pass the exit.
        """
        if not character:
            return True

        if self.can_bypass(character):
            return True

        triggered = False
        if defines.EVENT_TRIGGER_TRAVERSE in self.events:
            for event in self.events[defines.EVENT_TRIGGER_TRAVERSE]:
                # If has traverse event.
                if SCRIPT_HANDLER.match_condition(character, self.owner, event["condition"]):
                    # If matches the condition.
                    triggered = True
                    function = self.get_function(event["type"])
                    if function:
                        function(event, character)

        return not triggered
Пример #30
0
        def can_loot(self, looter, obj):
            """
            help function to decide which objects can be looted.

            Args:
                self: (object) this character
                looter: (object) who loot this character
                obj: (dict) information of the object which will be looted

            Returns:
                (boolean) if this object can be looted or not
            """
            rand = random.random()
            if rand > obj["odds"]:
                return False

            if obj["quest"]:
                if not looter.quest.is_not_accomplished(obj["quest"]):
                    return False

            if not SCRIPT_HANDLER.match_condition(looter, self, obj["condition"]):
                return False

            return True
Пример #31
0
    def get_next_sentences(self, caller, npc, current_dialogue, current_sentence):
        """
        Get current sentence's next sentences.
        """
        if not caller:
            return

        # Get current dialogue.
        dlg = self.get_dialogue(current_dialogue)
        if not dlg:
            return

        sentences = []

        try:
            # If has next sentence, use next sentence.
            sentences.append(dlg["sentences"][current_sentence + 1])
        except Exception, e:
            # Else get next dialogues.
            for dlg_key in dlg["nexts"]:
                # Get next dialogue.
                next_dlg = self.get_dialogue(dlg_key)
                if not next_dlg:
                    continue

                if not next_dlg["sentences"]:
                    continue

                if not SCRIPT_HANDLER.match_condition(caller, npc, next_dlg["condition"]):
                    continue

                for dep in next_dlg["dependencies"]:
                    if not QUEST_DEP_HANDLER.match_dependency(caller, dep["quest"], dep["type"]):
                        continue

                sentences.append(next_dlg["sentences"][0])
Пример #32
0
 def can_unlock(self, caller):
     """
     Unlock an exit.
     """
     # Only can unlock exits which match there conditions.
     return SCRIPT_HANDLER.match_condition(caller, self, self.exit_lock["condition"])