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
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
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()
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
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
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
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
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
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
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
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
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.
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}
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
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
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
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()
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
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
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
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.'
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
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
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
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
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