Пример #1
0
    def handle_action(self, pet_guid, target_guid, action):
        # Spell ID or 0/1/2/3 for setting command/react state.
        action_id = action & 0xFFFF

        active_pet_unit = self.active_pet.creature
        # Single active pet assumed.
        if active_pet_unit.guid != pet_guid:
            return

        if target_guid == 0:
            target_unit = self.owner
        else:
            target_unit = MapManager.get_surrounding_unit_by_guid(
                active_pet_unit, target_guid, include_players=True)

        if action_id > PetCommandState.COMMAND_DISMISS:  # Highest action ID.
            target_mask = SpellTargetMask.SELF if target_unit.guid == active_pet_unit.guid else SpellTargetMask.UNIT
            active_pet_unit.spell_manager.handle_cast_attempt(
                action_id, target_unit, target_mask)

        elif action & (0x01 << 24):
            # Command state action.
            self.get_active_pet_info().command_state = action_id
            self.active_pet.creature.object_ai.command_state_update()
            if action_id == PetCommandState.COMMAND_ATTACK and target_unit:
                self.active_pet.creature.object_ai.attack_start(target_unit)
            if action_id == PetCommandState.COMMAND_DISMISS:
                self.detach_active_pet()

        else:
            self.get_active_pet_info().react_state = action_id
    def handle(world_session, socket, reader):
        if len(reader.data
               ) >= 8:  # Avoid handling empty quest giver status packet.
            guid = unpack('<Q', reader.data[:8])[0]
            high_guid = ObjectManager.extract_high_guid(guid)

            quest_giver = None
            if high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)

            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_STATUS_QUERY, could not find quest giver with guid of: {guid}'
                )
                return 0

            # Only units are able to provide quest status.
            if world_session.player_mgr and quest_giver.get_type_id(
            ) == ObjectTypeIds.ID_UNIT:
                quest_giver_status = world_session.player_mgr.quest_manager.get_dialog_status(
                    quest_giver)
                world_session.player_mgr.quest_manager.send_quest_giver_status(
                    guid, quest_giver_status)

        return 0
Пример #3
0
    def handle(world_session, socket, reader):
        if len(
                reader.data
        ) >= 12:  # Avoid handling empty quest giver complete quest packet.
            guid, quest_id = unpack('<QI', reader.data[:12])
            high_guid = ObjectManager.extract_high_guid(guid)

            quest_giver = None
            if high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)

            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_COMPLETE_QUEST, could not find quest giver with guid of: {guid}'
                )
                return 0
            if world_session.player_mgr.is_enemy_to(quest_giver):
                return 0

            world_session.player_mgr.quest_manager.handle_complete_quest(
                quest_id, guid)
        return 0
Пример #4
0
    def __init__(self,
                 spell,
                 caster,
                 initial_target,
                 target_mask,
                 source_item=None,
                 triggered=False):
        self.spell_entry = spell
        self.spell_caster = caster
        self.source_item = source_item
        self.initial_target = initial_target
        self.spell_target_mask = target_mask
        self.triggered = triggered

        self.duration_entry = DbcDatabaseManager.spell_duration_get_by_id(
            spell.DurationIndex)
        self.range_entry = DbcDatabaseManager.spell_range_get_by_id(
            spell.RangeIndex)
        self.cast_time_entry = DbcDatabaseManager.spell_cast_time_get_by_id(
            spell.CastingTimeIndex)
        self.cast_end_timestamp = self.get_base_cast_time() / 1000 + time.time(
        )
        self.spell_visual_entry = DbcDatabaseManager.spell_visual_get_by_id(
            spell.SpellVisualID)

        if self.spell_caster.object_type_mask & ObjectTypeFlags.TYPE_UNIT:
            self.caster_effective_level = self.calculate_effective_level(
                self.spell_caster.level)
        else:
            self.caster_effective_level = 0

        # Resolve the weapon required for the spell.
        self.spell_attack_type = -1
        # Item target casts (enchants) have target item info in equipment requirements - ignore.
        if spell.EquippedItemClass == ItemClasses.ITEM_CLASS_WEAPON and not self.initial_target_is_item(
        ):
            self.spell_attack_type = AttackTypes.RANGED_ATTACK if self.is_ranged_weapon_attack(
            ) else AttackTypes.BASE_ATTACK

        self.cast_state = SpellState.SPELL_STATE_PREPARING
        self.spell_impact_timestamps = {}

        if caster.get_type_id() == ObjectTypeIds.ID_PLAYER:
            selection_guid = self.spell_caster.current_selection if self.spell_caster.current_selection else caster.guid
            self.targeted_unit_on_cast_start = MapManager.get_surrounding_unit_by_guid(
                self.spell_caster, selection_guid, include_players=True)

        if self.is_fishing_spell():
            # Locate liquid vector in front of the caster.
            self.initial_target = MapManager.find_liquid_location_in_range(
                self.spell_caster, self.range_entry.RangeMin,
                self.range_entry.RangeMax)
        self.cast_flags = SpellCastFlags.CAST_FLAG_NONE

        # Ammo needs to be resolved on initialization since it's needed for validation and spell cast packets.
        self.used_ranged_attack_item = self.get_ammo_for_cast()
        if self.used_ranged_attack_item:
            self.cast_flags |= SpellCastFlags.CAST_FLAG_HAS_AMMO

        self.load_effects()
Пример #5
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 8:  # Avoid handling empty trainer list packet.
            guid = unpack('<Q', reader.data[:8])[0]
            player_mgr = world_session.player_mgr

            # Player talents.
            if guid == player_mgr.guid:
                player_mgr.talent_manager.send_talent_list()
                return 0
            # NPC offering.
            else:
                trainer: CreatureManager = MapManager.get_surrounding_unit_by_guid(player_mgr, guid)

            if trainer and trainer.is_within_interactable_distance(player_mgr):
                available_quests: int = 0
                # Check if any quest is available.
                if trainer.is_quest_giver():
                    available_quests = player_mgr.quest_manager.get_active_quest_num_from_quest_giver(trainer)

                # If player does not meet requirements to talk to this Trainer, just send the quest giver greeting.
                # Ineligible quests won't show up here, so this matches the behavior of classic WoW.
                if not trainer.can_train(player_mgr) or available_quests > 0:
                    player_mgr.quest_manager.handle_quest_giver_hello(trainer, guid)
                elif trainer.can_train(player_mgr):
                    trainer.send_trainer_list(world_session)

        return 0
Пример #6
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 6:  # Avoid handling empty cast spell packet.
            spell_id, target_mask = unpack('<IH', reader.data[:6])

            caster = world_session.player_mgr

            if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN != 0 and len(
                    reader.data) >= 18:
                target_info = Vector.from_bytes(
                    reader.data[-12:])  # Terrain, target is vector
            elif len(reader.data) == 14:
                target_info = unpack(
                    '<Q', reader.data[-8:])[0]  # some object (read guid)
            else:
                target_info = caster  # Self

            if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN:
                spell_target = target_info
            elif target_mask & SpellTargetMask.UNIT and target_info != caster:
                spell_target = MapManager.get_surrounding_unit_by_guid(
                    caster, target_info, include_players=True)
            elif target_mask & SpellTargetMask.ITEM_TARGET_MASK:
                spell_target = caster.inventory.get_item_info_by_guid(
                    target_info)[3]  # (container_slot, container, slot, item)
            elif target_mask & SpellTargetMask.CAN_TARGET_OBJECTS:  # Can also include items so we check for that first
                spell_target = MapManager.get_surrounding_gameobject_by_guid(
                    caster, target_info)
            else:
                spell_target = caster  # Assume self cast for now. Invalid target will be resolved later

            world_session.player_mgr.spell_manager.handle_cast_attempt(
                spell_id, world_session.player_mgr, spell_target, target_mask)
        return 0
Пример #7
0
    def handle(world_session, socket, reader):
        if len(
                reader.data
        ) >= 12:  # Avoid handling empty quest giver request reward packet.
            guid, quest_id = unpack('<QI', reader.data[:12])
            high_guid = ObjectManager.extract_high_guid(guid)
            is_item = False

            quest_giver = None
            if high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_ITEM:
                is_item = True
                quest_giver = world_session.player_mgr.inventory.get_item_by_guid(
                    guid)

            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_REQUEST_REWARD, could not find quest giver with guid: {guid}'
                )
                return 0

            if not is_item and world_session.player_mgr.is_enemy_to(
                    quest_giver):
                return 0

            world_session.player_mgr.quest_manager.handle_request_reward(
                guid, quest_id)
        return 0
Пример #8
0
    def handle(world_session, socket, reader: PacketReader) -> int:
        if len(reader.data
               ) >= 8:  # Avoid handling empty debug AI state packet.
            guid = unpack('<Q', reader.data[:8])[0]

            high_guid: HighGuid = ObjectManager.extract_high_guid(guid)
            if high_guid == HighGuid.HIGHGUID_UNIT or high_guid == HighGuid.HIGHGUID_PLAYER:
                world_object = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid, include_players=True)
            else:
                world_object = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)

            # No object with that Guid? Return.
            if not world_object:
                return 0

            messages: list[str] = world_object.get_debug_messages()
            data = pack('<QI', guid, len(messages))

            for message in messages:
                message_bytes = PacketWriter.string_to_bytes(
                    message[:127])  # Max length is 128 (127 + null byte).
                data += pack(f'<{len(message_bytes)}s', message_bytes)

            world_session.enqueue_packet(
                PacketWriter.get_packet(OpCode.SMSG_DEBUG_AISTATE, data))

        return 0
Пример #9
0
    def handle(world_session, socket, reader):
        if len(reader.data
               ) >= 8:  # Avoid handling empty debug AI state packet.
            guid = unpack('<Q', reader.data[:8])[0]
            world_object = MapManager.get_surrounding_unit_by_guid(
                world_session.player_mgr, guid, include_players=True)

            # If no Unit or Player, try to get a Gameobject.
            if not world_object:
                world_object = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)

            # Still no object with that Guid? Return.
            if not world_object:
                return 0

            messages = world_object.get_debug_messages()
            data = pack('<QI', guid, len(messages))

            for message in messages:
                message_bytes = PacketWriter.string_to_bytes(
                    message[:127])  # Max length is 128 (127 + null byte).
                data += pack(f'<{len(message_bytes)}s', message_bytes)

            world_session.enqueue_packet(
                PacketWriter.get_packet(OpCode.SMSG_DEBUG_AISTATE, data))

        return 0
    def handle(world_session, socket, reader):
        if len(
                reader.data
        ) >= 12:  # Avoid handling empty quest giver accept quest packet.
            guid, quest_id = unpack('<QI', reader.data[:12])
            high_guid = ObjectManager.extract_high_guid(guid)
            is_item = False

            quest_giver = None
            if high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_ITEM:
                is_item = True
                quest_giver = world_session.player_mgr.inventory.get_item_by_guid(
                    guid)

            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_ACCEPT_QUEST, could not find quest giver with guid of: {guid}'
                )
                return 0
            elif not is_item and world_session.player_mgr.is_enemy_to(
                    quest_giver):
                return 0
            elif world_session.player_mgr.quest_manager.is_quest_log_full():
                world_session.enqueue_packet(
                    PacketWriter.get_packet(OpCode.SMSG_QUESTLOG_FULL))
            else:
                world_session.player_mgr.quest_manager.handle_accept_quest(
                    quest_id, guid, shared=False)
        return 0
Пример #11
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 8:  # Avoid handling empty quest giver status packet.
            quest_giver_guid = unpack('<Q', reader.data[:8])[0]
            quest_giver = None
            # NPC
            if quest_giver_guid & HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr, quest_giver_guid)
            # Gameobject
            elif quest_giver_guid & HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(world_session.player_mgr, quest_giver_guid)
            if not quest_giver:
                return 0

            quest_giver_status = QuestGiverStatus.QUEST_GIVER_NONE
            if world_session.player_mgr:
                if quest_giver.get_type() == ObjectTypes.TYPE_UNIT:
                    quest_giver_status = world_session.player_mgr.quest_manager.get_dialog_status(quest_giver)
                elif quest_giver.get_type() == ObjectTypes.TYPE_GAMEOBJECT:
                    # TODO: Proper handling for game object
                    quest_giver_status = QuestGiverStatus.QUEST_GIVER_NONE
                else:
                    Logger.error(f'Error in CMSG_QUESTGIVER_STATUS_QUERY, quest giver was an unexpected type of: {quest_giver.object_type}')

                world_session.player_mgr.quest_manager.send_quest_giver_status(quest_giver_guid, quest_giver_status)

        return 0
Пример #12
0
    def handle(world_session, socket, reader):
        if len(reader.data
               ) >= 8:  # Avoid handling empty quest giver hello packet.
            guid = unpack('<Q', reader.data[:8])[0]
            high_guid = ObjectManager.extract_high_guid(guid)

            quest_giver = None
            if high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid)
            elif high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(
                    world_session.player_mgr, guid)

            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_HELLO, could not find quest giver with guid of: {guid}'
                )
                return 0
            if world_session.player_mgr.is_enemy_to(quest_giver):
                return 0

            # TODO: Stop the npc if it's moving
            # TODO: Remove feign death from player (if it even exists in 0.5.3)
            # TODO: If the gossip menu is already open, do nothing
            if quest_giver.is_within_interactable_distance(
                    world_session.player_mgr):
                world_session.player_mgr.quest_manager.handle_quest_giver_hello(
                    quest_giver, guid)

        return 0
Пример #13
0
    def __init__(self,
                 spell,
                 caster_obj,
                 initial_target,
                 target_mask,
                 source_item=None):
        self.spell_entry = spell
        self.spell_caster = caster_obj
        self.source_item = source_item
        self.initial_target = initial_target
        self.spell_target_mask = target_mask
        self.duration_entry = DbcDatabaseManager.spell_duration_get_by_id(
            spell.DurationIndex)
        self.range_entry = DbcDatabaseManager.spell_range_get_by_id(
            spell.RangeIndex)  # TODO RangeMin is never used
        self.cast_time_entry = DbcDatabaseManager.spell_cast_time_get_by_id(
            spell.CastingTimeIndex)
        self.cast_end_timestamp = self.get_base_cast_time() / 1000 + time.time(
        )
        self.caster_effective_level = self.calculate_effective_level(
            self.spell_caster.level)

        self.spell_attack_type = -1  # Assigned on cast TODO Next ranged spells
        self.cast_state = SpellState.SPELL_STATE_PREPARING
        self.spell_impact_timestamps = {}

        if ObjectTypes.TYPE_PLAYER in caster_obj.object_type:
            self.targeted_unit_on_cast_start = MapManager.get_surrounding_unit_by_guid(
                self.spell_caster,
                self.spell_caster.current_selection,
                include_players=True)

        self.load_effects()

        self.cast_flags = SpellCastFlags.CAST_FLAG_NONE  # TODO Ammo/proc flag
Пример #14
0
    def get_target_info(world_session, target_mask, target_bytes):
        caster = world_session.player_mgr

        if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN != 0 and len(
                target_bytes) == 12:
            target_info = Vector.from_bytes(
                target_bytes)  # Terrain, target is vector.
        elif len(target_bytes) == 8:
            target_info = unpack('<Q',
                                 target_bytes)[0]  # Some object (read guid).
        else:
            target_info = caster  # Self

        if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN:
            return target_info
        if target_mask & SpellTargetMask.UNIT and target_info != caster:
            return MapManager.get_surrounding_unit_by_guid(
                caster, target_info, include_players=True)
        if target_mask & SpellTargetMask.ITEM_TARGET_MASK and not target_mask & SpellTargetMask.TRADE_ITEM:
            return caster.inventory.get_item_info_by_guid(target_info)[
                3]  # (container_slot, container, slot, item).
        if target_mask & SpellTargetMask.CAN_TARGET_OBJECTS:  # Can also include items, so we check for that first.
            return MapManager.get_surrounding_gameobject_by_guid(
                caster, target_info)
        if target_mask & SpellTargetMask.ITEM_TARGET_MASK and target_mask & SpellTargetMask.TRADE_ITEM:
            if caster.trade_data and caster.trade_data.other_player and caster.trade_data.other_player.trade_data:
                return caster.trade_data.other_player.trade_data.get_item_by_slot(
                    target_info)

        return caster  # Assume self cast for now. Invalid target will be resolved later.
Пример #15
0
    def is_quest_complete(self, quest_giver_guid):
        quest_giver = None
        high_guid = ObjectManager.extract_high_guid(quest_giver_guid)

        if high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
            quest_giver = MapManager.get_surrounding_gameobject_by_guid(self.owner, quest_giver_guid)
        elif high_guid == HighGuid.HIGHGUID_UNIT:
            quest_giver = MapManager.get_surrounding_unit_by_guid(self.owner, quest_giver_guid)

        if not quest_giver:
            return False

        if QuestHelpers.is_instant_complete_quest(self.quest):
            return True

        if self.db_state.state != QuestState.QUEST_REWARD:
            return False

        if quest_giver.get_type_id() == ObjectTypeIds.ID_UNIT and quest_giver.get_type_id() != ObjectTypeIds.ID_PLAYER:
            involved_relations_list = WorldDatabaseManager.QuestRelationHolder.creature_quest_finisher_get_by_entry(quest_giver.entry)
        elif quest_giver.get_type_id() == ObjectTypeIds.ID_GAMEOBJECT:
            involved_relations_list = WorldDatabaseManager.QuestRelationHolder.gameobject_quest_finisher_get_by_entry(quest_giver.entry)
        else:
            return False

        # Return if this quest is finished by this quest giver.
        return self.quest.entry in {quest_entry[1] for quest_entry in involved_relations_list}
Пример #16
0
    def handle(world_session, socket, reader):
        if world_session.player_mgr.is_alive and len(reader.data) >= 12:
            emote_text_id, guid = unpack('<IQ', reader.data)
            emote = DbcDatabaseManager.emote_text_get_by_id(emote_text_id)

            if emote:
                data = pack('<QI', world_session.player_mgr.guid,
                            emote_text_id)
                target = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid, include_players=True)

                if not target:
                    data += pack('<B', 0)
                elif target.get_type() == ObjectTypes.TYPE_PLAYER:
                    player_name_bytes = PacketWriter.string_to_bytes(
                        target.player.name)
                    data += pack(f'<{len(player_name_bytes)}s',
                                 player_name_bytes)
                elif target.get_type(
                ) == ObjectTypes.TYPE_UNIT and target.creature_template:
                    unit_name_bytes = PacketWriter.string_to_bytes(
                        target.creature_template.name)
                    data += pack(f'<{len(unit_name_bytes)}s', unit_name_bytes)
                else:
                    data += pack('<B', 0)

                MapManager.send_surrounding_in_range(
                    PacketWriter.get_packet(OpCode.SMSG_TEXT_EMOTE,
                                            data), world_session.player_mgr,
                    config.World.Chat.ChatRange.emote_range)

                # Perform visual emote action if needed

                emote_id = emote.EmoteID
                state = StandState.UNIT_STANDING
                needs_broadcast = True

                if emote_text_id == Emotes.SIT:
                    if not world_session.player_mgr.is_sitting:
                        state = StandState.UNIT_SITTING
                        world_session.player_mgr.set_stand_state(state)
                elif emote_text_id == Emotes.STAND:
                    world_session.player_mgr.set_stand_state(state)
                elif emote_text_id == Emotes.SLEEP:
                    if world_session.player_mgr.stand_state != StandState.UNIT_SLEEPING:
                        state = StandState.UNIT_SLEEPING
                    world_session.player_mgr.set_stand_state(state)
                elif emote_text_id == Emotes.KNEEL:
                    if world_session.player_mgr.stand_state != StandState.UNIT_KNEEL:
                        state = StandState.UNIT_KNEEL
                    world_session.player_mgr.set_stand_state(state)
                else:
                    needs_broadcast = False
                    world_session.player_mgr.play_emote(emote_id)

                if needs_broadcast:
                    world_session.player_mgr.set_dirty()

        return 0
Пример #17
0
 def handle(world_session, socket, reader):
     if len(reader.data) >= 8:  # Avoid handling empty banker activate packet.
         guid = unpack('<Q', reader.data[:8])[0]
         banker = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr, guid)
         if banker:
             data = pack('<Q', guid)
             world_session.enqueue_packet(PacketWriter.get_packet(OpCode.SMSG_SHOW_BANK, data))
     return 0
Пример #18
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 8:  # Avoid handling empty list inventory packet.
            npc_guid = unpack('<Q', reader.data[:8])[0]

            if npc_guid > 0:
                vendor = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr, npc_guid)
                if vendor:
                    vendor.send_inventory_list(world_session)

        return 0
Пример #19
0
    def handle_accept_quest(self, quest_id, quest_giver_guid, shared=False):
        if quest_id in self.active_quests:
            self.send_cant_take_quest_response(QuestFailedReasons.QUEST_ALREADY_ON)
            return

        if quest_id in self.completed_quests:
            self.send_cant_take_quest_response(QuestFailedReasons.QUEST_ONLY_ONE_TIMED)
            return

        quest_item_starter = None
        if quest_giver_guid:
            quest_giver = None
            high_guid = ObjectManager.extract_high_guid(quest_giver_guid)

            if high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(self.player_mgr, quest_giver_guid)
            elif high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(self.player_mgr, quest_giver_guid)
            elif high_guid == HighGuid.HIGHGUID_ITEM:
                quest_giver = self.player_mgr.inventory.get_item_by_guid(quest_giver_guid)
                quest_item_starter = quest_giver

            if not quest_giver:
                return

        quest = WorldDatabaseManager.QuestTemplateHolder.quest_get_by_entry(quest_id)
        if not quest:
            return

        req_src_item = quest.SrcItemId
        req_src_item_count = quest.SrcItemCount
        if req_src_item != 0:
            # Check if the required source item is the item quest starter, else check if we can add it to the inventory.
            if not quest_item_starter or quest_item_starter.entry != req_src_item:
                if not self.player_mgr.inventory.add_item(req_src_item, count=req_src_item_count):
                    return

        active_quest = self._create_db_quest_status(quest)
        active_quest.save(is_new=True)
        self.add_to_quest_log(quest_id, active_quest)
        self.send_quest_query_response(quest)

        # If player is in a group and quest has QUEST_FLAGS_PARTY_ACCEPT flag, let other members accept it too.
        if self.player_mgr.group_manager and not shared:
            quest_template = WorldDatabaseManager.QuestTemplateHolder.quest_get_by_entry(quest_id)
            if quest_template and quest_template.QuestFlags & QuestFlags.QUEST_FLAGS_PARTY_ACCEPT:
                self.share_quest_event(active_quest)

        # Check if the player already has related items.
        active_quest.update_required_items_from_inventory()
        if active_quest.can_complete_quest():
            self.complete_quest(active_quest, update_surrounding=False)

        self.update_surrounding_quest_status()
Пример #20
0
 def handle(world_session, socket, reader):
     if len(reader.data) >= 8:  # Avoid handling empty buy bank slot packet.
         guid = unpack('<Q', reader.data[:8])[0]
         banker = MapManager.get_surrounding_unit_by_guid(
             world_session.player_mgr, guid)
         if banker:
             next_slot = world_session.player_mgr.player.bankslots + 1
             slot_cost = DbcDatabaseManager.bank_get_slot_cost(next_slot)
             # Check if player can afford it (even if client already checks it)
             if world_session.player_mgr.coinage >= slot_cost:
                 world_session.player_mgr.add_bank_slot(slot_cost)
     return 0
Пример #21
0
    def handle(world_session, socket, reader):
        if len(reader.data
               ) >= 8:  # Avoid handling empty quest giver query quest packet.
            guid, quest_entry = unpack('<QL', reader.data[:12])
            high_guid = ObjectManager.extract_high_guid(guid)

            # NPC
            if high_guid == HighGuid.HIGHGUID_UNIT:
                quest_giver = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, guid)
                if not quest_giver:
                    return 0

                quest_giver_is_related = world_session.player_mgr.quest_manager.check_quest_giver_npc_is_related(
                    quest_giver.entry, quest_entry)
                if not quest_giver_is_related:
                    return 0
            # Gameobject
            elif high_guid == HighGuid.HIGHGUID_GAMEOBJECT:
                quest_giver = MapManager.get_surrounding_gameobject_by_guid(
                    world_session, guid)
                if not quest_giver:
                    return 0
            # Item
            elif high_guid == HighGuid.HIGHGUID_ITEM:
                item_info = world_session.player_mgr.inventory.get_item_info_by_guid(
                    guid)
                if not item_info[3]:
                    return 0

                quest_giver = item_info[3].item_template
                quest_giver_is_related = quest_giver.start_quest == quest_entry
                if not quest_giver_is_related:
                    return 0
            else:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_QUERY_QUEST, unknown quest giver type.'
                )
                return 0

            quest = WorldDatabaseManager.QuestTemplateHolder.quest_get_by_entry(
                quest_entry)
            if not quest:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_QUERY_QUEST, could not find quest with an entry of: {quest_entry}'
                )
                return 0

            world_session.player_mgr.quest_manager.send_quest_giver_quest_details(
                quest, guid, True)

        return 0
Пример #22
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 8:  # Avoid handling empty attack swing packet.
            # TODO: Finish implementing this
            enemy_guid = unpack('<Q', reader.data[:8])[0]
            enemy = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr, enemy_guid, include_players=True)

            if not enemy or not enemy.is_alive:
                AttackSwingHandler.handle_stop(world_session, socket, reader)
                return 0

            world_session.player_mgr.attack(enemy)

        return 0
Пример #23
0
    def creature_info(world_session, args):
        creature = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr,
                                                           world_session.player_mgr.current_selection)

        if creature:
            return 0, f'[{creature.creature_template.name}] - Guid: {creature.guid & ~HighGuid.HIGHGUID_UNIT}, ' \
                      f'Entry: {creature.creature_template.entry}, ' \
                      f'Display ID: {creature.current_display_id}, ' \
                      f'X: {creature.location.x}, ' \
                      f'Y: {creature.location.y}, ' \
                      f'Z: {creature.location.z}, ' \
                      f'O: {creature.location.o}, ' \
                      f'Map: {creature.map_}'
        return -1, 'error retrieving creature info.'
Пример #24
0
    def _target_or_self(world_session, only_players=False):
        if world_session.player_mgr.current_selection \
                and world_session.player_mgr.current_selection != world_session.player_mgr.guid:
            if only_players:
                unit = MapManager.get_surrounding_player_by_guid(world_session.player_mgr,
                                                                 world_session.player_mgr.current_selection)
            else:
                unit = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr,
                                                               world_session.player_mgr.current_selection,
                                                               include_players=True)
            if unit:
                return unit

        return world_session.player_mgr
Пример #25
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 12:  # Avoid handling empty creature query packet.
            entry, guid = unpack('<IQ', reader.data[:12])
            if guid > 0:
                creature_mgr = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr, guid)
                if not creature_mgr:
                    creature_spawn, session = WorldDatabaseManager.creature_spawn_get_by_guid(guid)
                    if creature_spawn and creature_spawn.creature_template.entry == entry:
                        creature_mgr = CreatureManager(
                            creature_template=creature_spawn.creature_template
                        )
                    session.close()
                if creature_mgr:
                    world_session.enqueue_packet(creature_mgr.query_details())

        return 0
Пример #26
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 22:  # Avoid handling empty buy item packet.
            vendor_guid, item, bag_guid, slot, count = unpack(
                '<QIQ2B', reader.data[:22])
            if vendor_guid > 0:
                if count <= 0:
                    count = 1

                vendor_npc = MapManager.get_surrounding_unit_by_guid(
                    world_session.player_mgr, vendor_guid)

                vendor_data, session = WorldDatabaseManager.creature_get_vendor_data_by_item(
                    vendor_npc.entry, item)

                if vendor_data:
                    item_template = vendor_data.item_template
                    session.close()

                    total_cost = item_template.buy_price * count
                    real_count = count if item_template.buy_count == 1 else item_template.buy_count

                    if world_session.player_mgr.coinage < total_cost:
                        world_session.player_mgr.inventory.send_buy_error(
                            BuyResults.BUY_ERR_NOT_ENOUGH_MONEY, item,
                            vendor_guid, real_count)
                        return 0

                    if 0 < vendor_data.maxcount < count:  # I should be checking here for current count too
                        world_session.player_mgr.inventory.send_buy_error(
                            BuyResults.BUY_ERR_ITEM_SOLD_OUT, item,
                            vendor_guid, real_count)
                        return 0

                    bag_slot = world_session.player_mgr.inventory.get_container_slot_by_guid(
                        bag_guid)
                    if world_session.player_mgr.inventory.add_item_to_slot(
                            dest_bag_slot=bag_slot,
                            dest_slot=slot,
                            item_template=item_template,
                            count=real_count):
                        world_session.player_mgr.mod_money(total_cost * -1)
                        # vendor_npc.send_inventory_list(world_session)
                else:
                    world_session.player_mgr.inventory.send_buy_error(
                        BuyResults.BUY_ERR_CANT_FIND_ITEM, item, vendor_guid)

        return 0
Пример #27
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 8:  # Avoid handling empty loot packet.
            loot_target_guid = unpack('<Q', reader.data[:8])[0]
            player = world_session.player_mgr
            enemy = MapManager.get_surrounding_unit_by_guid(
                world_session.player_mgr,
                loot_target_guid,
                include_players=False)

            if player and enemy:
                # Only set flag if player was able to loot, else the player would be kneeling forever.
                if player.send_loot(enemy.loot_manager):
                    player.unit_flags |= UnitFlags.UNIT_FLAG_LOOTING
                    player.set_uint32(UnitFields.UNIT_FIELD_FLAGS,
                                      player.unit_flags)

        return 0
    def handle(world_session, socket, reader):
        if len(
                reader.data
        ) >= 12:  # Avoid handling empty quest giver complete quest packet.
            quest_giver_guid, quest_id = unpack('<QI', reader.data[:12])
            quest_giver = MapManager.get_surrounding_unit_by_guid(
                world_session.player_mgr, quest_giver_guid)
            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_COMPLETE_QUEST, could not find quest giver with guid of: {quest_giver_guid}'
                )
                return 0
            if world_session.player_mgr.is_enemy_to(quest_giver):
                return 0

            world_session.player_mgr.quest_manager.handle_complete_quest(
                quest_id, quest_giver_guid)
        return 0
Пример #29
0
    def handle(world_session, socket, reader):
        if len(reader.data) >= 8:  # Avoid handling empty list inventory packet.
            npc_guid = unpack('<Q', reader.data[:8])[0]
            if npc_guid <= 0:
                return 0

            vendor: CreatureManager = MapManager.get_surrounding_unit_by_guid(world_session.player_mgr, npc_guid)
            if vendor and vendor.location.distance(world_session.player_mgr.location) < Formulas.Distances.MAX_SHOP_DISTANCE:
                # If vendor is a quest giver and player has an active quest involving this NPC, send quest window
                # instead of vendor window.
                if vendor.is_quest_giver():
                    quests: int = world_session.player_mgr.quest_manager.get_active_quest_num_from_quest_giver(vendor)
                    if quests > 0:
                        world_session.player_mgr.quest_manager.handle_quest_giver_hello(vendor, npc_guid)
                        return 0

                vendor.send_inventory_list(world_session)
        return 0
    def handle(world_session, socket, reader):
        # CGPlayer_C::GetQuestReward
        if len(
                reader.data
        ) >= 16:  # Avoid handling empty quest fiver choose reward packet.
            quest_giver_guid, quest_id, item_choice = unpack(
                '<Q2I', reader.data[:16])
            quest_giver = MapManager.get_surrounding_unit_by_guid(
                world_session.player_mgr, quest_giver_guid)
            if not quest_giver:
                Logger.error(
                    f'Error in CMSG_QUESTGIVER_COMPLETE_QUEST, could not find quest giver with guid of: {quest_giver_guid}'
                )
                return 0
            if world_session.player_mgr.is_enemy_to(quest_giver):
                return 0

            world_session.player_mgr.quest_manager.handle_choose_reward(
                quest_giver_guid, quest_id, item_choice)
        return 0