示例#1
0
    def get_progress(self):
        total_count = 0

        # Handle exploration, all bits set if completed.
        if self.is_exploration_quest() and self.get_quest_state() == QuestState.QUEST_REWARD:
            return total_count ^ 0xFFFFFFFF

        # Creature or gameobject.
        req_creature_or_go = QuestHelpers.generate_req_creature_or_go_list(self.quest)
        req_creature_or_go_count = QuestHelpers.generate_req_creature_or_go_count_list(self.quest)
        for index, creature_or_go in enumerate(req_creature_or_go):
            if req_creature_or_go[index] > 0:
                current_count = eval(f'self.db_state.mobcount{index + 1}')
                required = req_creature_or_go_count[index]
                # Consider how many bits the previous creature required.
                offset = index * req_creature_or_go_count[index - 1] if index > 0 else 0

                for i in range(required):
                    if i < current_count:  # Turn on actual kills
                        total_count += (1 & 1) << (1 * i) + offset
                    else:  # Fill remaining 0s (Missing kills)
                        total_count += 0 << (1 * i) + offset

                # Debug, enable this to take a look on whats happening at bit level.
                # Logger.debug(f'{bin(mob_kills)[2:].zfill(32)}')

        return total_count
示例#2
0
 def requires_creature_or_go(self, creature_entry):
     req_creatures_or_gos = QuestHelpers.generate_req_creature_or_go_list(self.quest)
     required = creature_entry in req_creatures_or_gos
     if required:
         index = req_creatures_or_gos.index(creature_entry)
         required_kills = QuestHelpers.generate_req_creature_or_go_count_list(self.quest)[index]
         current_kills = eval(f'self.db_state.mobcount{index + 1}')
         return current_kills < required_kills
     return False
示例#3
0
 def update_creature_go_count(self, creature, value):
     creature_go_index = QuestHelpers.generate_req_creature_or_go_list(self.quest).index(creature.entry)
     required = QuestHelpers.generate_req_creature_or_go_count_list(self.quest)[creature_go_index]
     current = self._get_db_mob_or_go_count(creature_go_index)
     # Current < Required is already validated on requires_creature_or_go().
     self._update_db_creature_go_count(creature_go_index, 1)  # Update db memento
     # Notify the current objective count to the player.
     data = pack('<4IQ', self.db_state.quest, creature.entry, current + value, required, creature.guid)
     packet = PacketWriter.get_packet(OpCode.SMSG_QUESTUPDATE_ADD_KILL, data)
     self.owner.enqueue_packet(packet)
     # Check if this makes it complete.
     if self.can_complete_quest():
         self.update_quest_state(QuestState.QUEST_REWARD)
示例#4
0
    def is_instant_complete_quest(self):
        for reqSource in QuestHelpers.generate_req_source_list(self.quest):
            if reqSource != 0:
                return False

        for reqItem in QuestHelpers.generate_req_item_list(self.quest):
            if reqItem != 0:
                return False

        for reqCreatureGo in QuestHelpers.generate_req_creature_or_go_list(
                self.quest):
            if reqCreatureGo != 0:
                return False

        for reqSpellCast in QuestHelpers.generate_req_spell_cast_list(
                self.quest):
            if reqSpellCast != 0:
                return False

        return True
示例#5
0
    def get_progress(self):
        total_count = 0
        req_creature_or_go = QuestHelpers.generate_req_creature_or_go_list(
            self.quest)
        req_creature_or_go_count = QuestHelpers.generate_req_creature_or_go_count_list(
            self.quest)
        for index, creature_or_go in enumerate(req_creature_or_go):
            if req_creature_or_go[index] > 0:
                current_count = eval(f'self.db_state.mobcount{index + 1}')
                required = req_creature_or_go_count[index]
                # Consider how many bits the previous creature required.
                offset = index * req_creature_or_go_count[
                    index - 1] if index > 0 else 0

                for i in range(0, required):
                    if i < current_count:  # Turn on actual kills
                        total_count += (1 & 1) << (1 * i) + offset
                    else:  # Fill remaining 0s (Missing kills)
                        total_count += 0 << (1 * i) + offset

                # Debug, enable this to take a look on whats happening at bit level.
                # Logger.debug(f'{bin(mob_kills)[2:].zfill(32)}')

        return total_count
示例#6
0
    def send_quest_query_response(self, quest):
        data = pack(f'<3Ii4I', quest.entry, quest.Method, quest.QuestLevel,
                    quest.ZoneOrSort, quest.Type, quest.NextQuestInChain,
                    quest.RewOrReqMoney, quest.SrcItemId)

        # Rewards given no matter what.
        rew_item_list = QuestHelpers.generate_rew_item_list(quest)
        rew_item_count_list = QuestHelpers.generate_rew_count_list(quest)
        for index, item in enumerate(rew_item_list):
            data += pack('<2I', item, rew_item_count_list[index])

        # Reward choices.
        rew_choice_item_list = QuestHelpers.generate_rew_choice_item_list(
            quest)
        rew_choice_count_list = QuestHelpers.generate_rew_choice_count_list(
            quest)
        for index, item in enumerate(rew_choice_item_list):
            data += pack('<2I', item, rew_choice_count_list[index])

        title_bytes = PacketWriter.string_to_bytes(quest.Title)
        details_bytes = PacketWriter.string_to_bytes(quest.Details)
        objectives_bytes = PacketWriter.string_to_bytes(quest.Objectives)
        end_bytes = PacketWriter.string_to_bytes(quest.EndText)
        data += pack(
            f'<I2fI{len(title_bytes)}s{len(details_bytes)}s{len(objectives_bytes)}s{len(end_bytes)}s',
            quest.PointMapId,
            quest.PointX,
            quest.PointY,
            quest.PointOpt,
            title_bytes,
            details_bytes,
            objectives_bytes,
            end_bytes,
        )

        # Required kills / Required items count.
        req_creatures_or_gos = QuestHelpers.generate_req_creature_or_go_list(
            quest)
        req_creatures_or_gos_count_list = QuestHelpers.generate_req_creature_or_go_count_list(
            quest)
        req_items = QuestHelpers.generate_req_item_list(quest)
        req_items_count_list = QuestHelpers.generate_req_item_count_list(quest)
        for index, creature_or_go in enumerate(req_creatures_or_gos):
            data += pack(
                '<4IB',
                creature_or_go if creature_or_go >= 0 else
                (creature_or_go * -1) | 0x80000000,
                req_creatures_or_gos_count_list[index],
                req_items[index],
                req_items_count_list[index],
                0x0  # Unknown, if missing, multiple objective quests will not display properly.
            )

        # Objective texts.
        req_objective_text_list = QuestHelpers.generate_objective_text_list(
            quest)
        for index, objective_text in enumerate(req_objective_text_list):
            req_objective_text_bytes = PacketWriter.string_to_bytes(
                req_objective_text_list[index])
            data += pack(f'{len(req_objective_text_bytes)}s',
                         req_objective_text_bytes)

        self.player_mgr.enqueue_packet(
            PacketWriter.get_packet(OpCode.SMSG_QUEST_QUERY_RESPONSE, data))
示例#7
0
    def send_quest_giver_quest_details(self, quest_template, quest_giver_guid,
                                       activate_accept):
        # Quest information
        quest_title = PacketWriter.string_to_bytes(quest_template.Title)
        quest_details = PacketWriter.string_to_bytes(quest_template.Details)
        quest_objectives = PacketWriter.string_to_bytes(
            quest_template.Objectives)
        data = pack(
            f'<QI{len(quest_title)}s{len(quest_details)}s{len(quest_objectives)}sI',
            quest_giver_guid, quest_template.entry, quest_title, quest_details,
            quest_objectives, 1 if activate_accept else 0)

        # Reward choices
        rew_choice_item_list = list(
            filter((0).__ne__,
                   QuestHelpers.generate_rew_choice_item_list(quest_template)))
        rew_choice_count_list = list(
            filter(
                (0).__ne__,
                QuestHelpers.generate_rew_choice_count_list(quest_template)))
        data += pack('<I', len(rew_choice_item_list))
        for index, item in enumerate(rew_choice_item_list):
            data += self._gen_item_struct(item, rew_choice_count_list[index])

        # Reward items
        rew_item_list = list(
            filter((0).__ne__,
                   QuestHelpers.generate_rew_item_list(quest_template)))
        rew_count_list = list(
            filter((0).__ne__,
                   QuestHelpers.generate_rew_count_list(quest_template)))
        data += pack('<I', len(rew_item_list))
        for index, item in enumerate(rew_item_list):
            data += self._gen_item_struct(item, rew_count_list[index])

        # Reward money
        data += pack('<I', quest_template.RewOrReqMoney)

        # Required items
        req_item_list = list(
            filter((0).__ne__,
                   QuestHelpers.generate_req_item_list(quest_template)))
        req_count_list = list(
            filter((0).__ne__,
                   QuestHelpers.generate_req_item_count_list(quest_template)))
        data += pack('<I', len(req_item_list))
        for index, item in enumerate(req_item_list):
            data += self._gen_item_struct(item, req_count_list[index])

        # Required kill / go count
        req_creature_or_go_list = list(
            filter(
                (0).__ne__,
                QuestHelpers.generate_req_creature_or_go_list(quest_template)))
        req_creature_or_go_count_list = list(
            filter((0).__ne__,
                   QuestHelpers.generate_req_creature_or_go_count_list(
                       quest_template)))
        data += pack('<I', len(req_creature_or_go_list))
        for index, creature_or_go in enumerate(req_creature_or_go_list):
            data += pack(
                '<2I', creature_or_go if creature_or_go >= 0 else
                (creature_or_go * -1) | 0x80000000,
                req_creature_or_go_count_list[index])

        self.player_mgr.enqueue_packet(
            PacketWriter.get_packet(OpCode.SMSG_QUESTGIVER_QUEST_DETAILS,
                                    data))