def load_taxi_nodes(): taxi_nodes = DbcDatabaseManager.taxi_nodes_get_all() length = len(taxi_nodes) count = 0 for taxi_node in taxi_nodes: DbcDatabaseManager.TaxiNodesHolder.load_taxi_node(taxi_node) count += 1 Logger.progress('Loading taxi nodes...', count, length)
def sskill(world_session, args): skill_name = args.strip() if not skill_name: return -1, 'please specify a skill name to start searching.' skills = DbcDatabaseManager.skill_get_by_name(skill_name) for skill in skills: skill_name = skill.DisplayName_enUS.replace('\\', '') skill_text = f'{skill.ID} - |cFF00FFFF[{skill_name}]|r' ChatManager.send_system_message(world_session, skill_text) return 0, f'{len(skills)} skills found.'
def load_skill_line_abilities(): skill_line_abilities = DbcDatabaseManager.skill_line_ability_get_all() length = len(skill_line_abilities) count = 0 for skill_line_ability in skill_line_abilities: DbcDatabaseManager.SkillLineAbilityHolder.load_skill_line_ability( skill_line_ability) count += 1 Logger.progress('Loading skill line abilities...', count, length)
def handle(world_session, socket, reader: PacketReader) -> int: if len(reader.data) >= 4: # Avoid handling empty trigger cinematic cheat packet. if not world_session.player_mgr.is_gm: return 0 cinematic_id = unpack('<I', reader.data[:4])[0] if DbcDatabaseManager.cinematic_sequences_get_by_id(cinematic_id): data = pack('<I', cinematic_id) world_session.enqueue_packet(PacketWriter.get_packet(OpCode.SMSG_TRIGGER_CINEMATIC, data)) return 0
def sspell(world_session, args): spell_name = args.strip() if not spell_name: return -1, 'please specify a spell name to start searching.' spells = DbcDatabaseManager.spell_get_by_name(spell_name) for spell in spells: spell_text = '%u - |cFF00FFFF[%s]|r' % (spell.ID, spell.Name_enUS.replace('\\', '')) spell_text += ' (%s)' % spell.NameSubtext_enUS if spell.NameSubtext_enUS else '' ChatManager.send_system_message(world_session, spell_text) return 0, '%u spells found.' % len(spells)
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_id() == ObjectTypeIds.ID_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_id( ) == ObjectTypeIds.ID_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 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: world_session.player_mgr.play_emote(emote_id) return 0
def load_spells(): spells: list[Spell] = DbcDatabaseManager.spell_get_all() length = len(spells) count = 0 for spell in spells: DbcDatabaseManager.SpellHolder.load_spell(spell) count += 1 Logger.progress('Loading spells...', count, length) return length
def load_locks(): locks = DbcDatabaseManager.locks_get_all() length = len(locks) count = 0 for lock in locks: DbcDatabaseManager.LocksHolder.load_lock(lock) count += 1 Logger.progress('Loading locks...', count, length) return length
def load_skills(): skills = DbcDatabaseManager.skill_get_all() length = len(skills) count = 0 for skill in skills: DbcDatabaseManager.SkillHolder.load_skill(skill) count += 1 Logger.progress('Loading skills...', count, length) return length
def load_factions(): factions = DbcDatabaseManager.faction_get_all() length = len(factions) count = 0 for faction in factions: DbcDatabaseManager.FactionHolder.load_faction(faction) count += 1 Logger.progress('Loading factions...', count, length) return length
def resume_taxi_flight(self): taxi_path = DbcDatabaseManager.taxi_path_get( self.taxi_resume_info.start_node, self.taxi_resume_info.dest_node) if taxi_path: return self.begin_taxi_flight( taxi_path, self.taxi_resume_info.start_node, self.taxi_resume_info.dest_node, mount_display_id=self.taxi_resume_info.mount_display_id, remaining_wp=self.taxi_resume_info.remaining_waypoints) else: return False
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 load_char_base_infos(): char_base_infos = DbcDatabaseManager.char_base_info_get_all() length = len(char_base_infos) count = 0 for char_base_info in char_base_infos: DbcDatabaseManager.CharBaseInfoHolder.load_base_info( char_base_info) count += 1 Logger.progress('Loading char base infos...', count, length) return length
def load_faction_templates(): faction_templates = DbcDatabaseManager.faction_template_get_all() length = len(faction_templates) count = 0 for faction_template in faction_templates: DbcDatabaseManager.FactionTemplateHolder.load_faction_template( faction_template) count += 1 Logger.progress('Loading faction templates...', count, length) return length
def update(self, entry, duration, charges): self.entry = entry self.duration = duration self.charges = charges # Update enchantments data. self.spell_item_enchantment_entry = DbcDatabaseManager.spell_get_item_enchantment( entry) if self.spell_item_enchantment_entry: self.effect = self.spell_item_enchantment_entry.Effect_1 self.effect_points = self.spell_item_enchantment_entry.EffectPointsMin_1 self.effect_spell = self.spell_item_enchantment_entry.EffectArg_1 self.aura_id = self.spell_item_enchantment_entry.ItemVisual
def sspell(world_session, args): spell_name = args.strip() if not spell_name: return -1, 'please specify a spell name to start searching.' spells = DbcDatabaseManager.spell_get_by_name(spell_name) for spell in spells: spell_name = spell.Name_enUS.replace('\\', '') spell_subtext = spell.NameSubtext_enUS if spell.NameSubtext_enUS else '' spell_text = f'{spell.ID} - |cFF00FFFF[{spell_name}]|r' spell_text += f' ({spell_subtext})' ChatManager.send_system_message(world_session, spell_text) return 0, f'{len(spells)} spells found.'
def __init__(self, spell, caster_obj, initial_target, target_mask): self.spell_entry = spell self.spell_caster = caster_obj 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) 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 = AttackTypes.RANGED_ATTACK if self.is_ranged( ) else AttackTypes.BASE_ATTACK self.cast_state = SpellState.SPELL_STATE_PREPARING self.effects = self.load_effects() self.cast_flags = SpellCastFlags.CAST_FLAG_NONE # TODO Ammo/proc flag
def load_creature_families(): creature_families = DbcDatabaseManager.creature_family_get_all() length = len(creature_families) count = 0 for creature_family in creature_families: DbcDatabaseManager.CreatureFamilyHolder.load_creature_family( creature_family) count += 1 Logger.progress('Loading creature families...', count, length) return length
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() 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: 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 # 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
def handle(world_session, socket, reader): if len(reader.data ) >= 16: # Avoid handling empty activate taxi packet. guid, start_node, dest_node = unpack('<Q2I', reader.data[:16]) if guid <= 0: return result = ActivateTaxiReplies.ERR_TAXIOK if world_session.player_mgr.in_combat: result = ActivateTaxiReplies.ERR_TAXIPLAYERBUSY elif world_session.player_mgr.mount_display_id > 0: result = ActivateTaxiReplies.ERR_TAXIPLAYERALREADYMOUNTED taxi_path = DbcDatabaseManager.taxi_path_get(start_node, dest_node) if not taxi_path: result = ActivateTaxiReplies.ERR_TAXINOSUCHPATH if world_session.player_mgr.coinage < taxi_path.Cost: result = ActivateTaxiReplies.ERR_TAXINOTENOUGHMONEY data = pack('<I', result) world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_ACTIVATETAXIREPLY, data)) if result == ActivateTaxiReplies.ERR_TAXIOK: world_session.player_mgr.mod_money(-taxi_path.Cost) waypoints = [] taxi_path_nodes = DbcDatabaseManager.TaxiPathNodesHolder.taxi_nodes_get_by_path_id( taxi_path.ID) for taxi_path_node in taxi_path_nodes: waypoints.append( Vector(taxi_path_node.LocX, taxi_path_node.LocY, taxi_path_node.LocZ)) world_session.player_mgr.unit_flags |= UnitFlags.UNIT_FLAG_FROZEN | UnitFlags.UNIT_FLAG_TAXI_FLIGHT world_session.player_mgr.set_uint32( UnitFields.UNIT_FIELD_FLAGS, world_session.player_mgr.unit_flags) dest_taxi_node = DbcDatabaseManager.TaxiNodesHolder.taxi_nodes_get_by_map_and_id( world_session.player_mgr.map_, dest_node) world_session.player_mgr.pending_taxi_destination = Vector( dest_taxi_node.X, dest_taxi_node.Y, dest_taxi_node.Z) world_session.player_mgr.mount(GRYPHON_DISPLAY_ID) world_session.player_mgr.set_dirty() world_session.player_mgr.movement_manager.send_move_to( waypoints, config.Unit.Player.Defaults.flight_speed, SplineFlags.SPLINEFLAG_FLYING) return 0
def load_creature_display_info(): creature_display_infos = DbcDatabaseManager.creature_display_info_get_all( ) length = len(creature_display_infos) count = 0 for creature_display_info in creature_display_infos: DbcDatabaseManager.CreatureDisplayInfoHolder.load_creature_display_info( creature_display_info) count += 1 Logger.progress('Loading creature display info...', count, length) return length
def __init__(self, casting_spell, index): if index == 0: self.load_first(casting_spell.spell_entry) elif index == 1: self.load_second(casting_spell.spell_entry) elif index == 2: self.load_third(casting_spell.spell_entry) self.caster_effective_level = casting_spell.caster_effective_level self.targets = EffectTargets(casting_spell, self) self.radius_entry = DbcDatabaseManager.spell_radius_get_by_id( self.radius_index) if self.radius_index else None self.trigger_spell_entry = DbcDatabaseManager.SpellHolder.spell_get_by_id( self.trigger_spell_id) if self.trigger_spell_id else None self.duration_entry = casting_spell.duration_entry
def __init__(self, casting_spell, index): if index == 0: self.load_first(casting_spell.spell_entry) elif index == 1: self.load_second(casting_spell.spell_entry) elif index == 2: self.load_third(casting_spell.spell_entry) self.caster_effective_level = casting_spell.caster_effective_level self.targets = EffectTargets(casting_spell, self) self.radius_entry = DbcDatabaseManager.spell_radius_get_by_id(self.radius_index) if self.radius_index else None self.duration_entry = casting_spell.duration_entry is_periodic = self.aura_type in PERIODIC_AURA_EFFECTS # Descriptions of periodic effects with a period of 0 either imply regeneration every 5s or say "per tick". self.aura_period = (self.aura_period if self.aura_period else 5000) if is_periodic else 0
def use(self, player): if self.gobject_template.type == GameObjectTypes.TYPE_DOOR or \ self.gobject_template.type == GameObjectTypes.TYPE_BUTTON: # TODO: Check locks for doors if self.state == GameObjectStates.GO_STATE_READY: self.state = GameObjectStates.GO_STATE_ACTIVE # TODO: Trigger sripts / events on cooldown restart self.send_update_surrounding() elif self.gobject_template.type == GameObjectTypes.TYPE_CAMERA: cinematic_id = self.gobject_template.data1 if DbcDatabaseManager.cinematic_sequences_get_by_id(cinematic_id): data = pack('<I', cinematic_id) player.session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_TRIGGER_CINEMATIC, data)) elif self.gobject_template.type == GameObjectTypes.TYPE_CHAIR: slots = self.gobject_template.data0 height = self.gobject_template.data1 lowest_distance = 90.0 x_lowest = self.location.x y_lowest = self.location.y if slots > 0: orthogonal_orientation = self.location.o + pi * 0.5 for x in range(0, slots): relative_distance = (self.current_scale * x) - (self.current_scale * (slots - 1) / 2.0) x_i = self.location.x + relative_distance * cos( orthogonal_orientation) y_i = self.location.y + relative_distance * sin( orthogonal_orientation) player_slot_distance = player.location.distance( Vector(x_i, y_i, player.location.z)) if player_slot_distance <= lowest_distance: lowest_distance = player_slot_distance x_lowest = x_i y_lowest = y_i player.teleport( player.map_, Vector(x_lowest, y_lowest, self.location.z, self.location.o)) player.set_stand_state(StandState.UNIT_SITTINGCHAIRLOW.value + height)
def generate_starting_items(guid, race, class_, gender): start_items = DbcDatabaseManager.char_start_outfit_get( race, class_, gender) items_to_add = [ start_items.ItemID_1, start_items.ItemID_2, start_items.ItemID_3, start_items.ItemID_4, start_items.ItemID_5, start_items.ItemID_6, start_items.ItemID_7, start_items.ItemID_8, start_items.ItemID_9, start_items.ItemID_10, start_items.ItemID_11, start_items.ItemID_12 ] last_bag_slot = InventorySlots.SLOT_INBACKPACK.value for entry in items_to_add: item = ItemManager.generate_starting_item(guid, entry, last_bag_slot) if item and item.item_instance: RealmDatabaseManager.character_inventory_add_item( item.item_instance) if item.current_slot >= InventorySlots.SLOT_INBACKPACK: last_bag_slot += 1
def preload_model_info(self): if self.creature_template and self.creature_instance: if not self.model_info_loaded: creature_model_info = WorldDatabaseManager.creature_get_model_info( self.display_id) if creature_model_info: self.bounding_radius = creature_model_info.bounding_radius self.combat_reach = creature_model_info.combat_reach if self.creature_template.scale == 0: display_scale = DbcDatabaseManager.creature_display_info_get_by_id( self.display_id) if display_scale and display_scale.CreatureModelScale > 0: self.scale = display_scale.CreatureModelScale else: self.scale = 1 else: self.scale = self.creature_template.scale self.model_info_loaded = True
def __init__(self, casting_spell, index): if index == 0: self.load_first(casting_spell.spell_entry) elif index == 1: self.load_second(casting_spell.spell_entry) elif index == 2: self.load_third(casting_spell.spell_entry) self.caster_effective_level = casting_spell.caster_effective_level self.targets = EffectTargets(casting_spell, self) self.radius_entry = DbcDatabaseManager.spell_radius_get_by_id( self.radius_index) if self.radius_index else None self.trigger_spell_entry = DbcDatabaseManager.SpellHolder.spell_get_by_id( self.trigger_spell_id) if self.trigger_spell_id else None if self.aura_type and casting_spell.initial_target_is_terrain( ): # TODO only needed when terrain is target? self.effect_aura = AppliedAura( casting_spell.spell_caster, casting_spell, self, None ) # Target as none as this effect shouldn't be tied to any unit
def handle(world_session, socket, reader: PacketReader) -> int: player_mgr = world_session.player_mgr if not player_mgr: return 0 if not player_mgr.is_gm: Logger.anticheat( f'Player {player_mgr.player.name} ({player_mgr.guid}) tried to force trigger a cinematic.' ) return 0 if len(reader.data ) >= 4: # Avoid handling empty trigger cinematic cheat packet. cinematic_id = unpack('<I', reader.data[:4])[0] if DbcDatabaseManager.cinematic_sequences_get_by_id(cinematic_id): data = pack('<I', cinematic_id) world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_TRIGGER_CINEMATIC, data)) return 0
def handle(world_session, socket, reader): if len(reader.data ) >= 16: # Avoid handling empty activate taxi packet. guid, start_node, dest_node = unpack('<Q2I', reader.data[:16]) flight_master = MapManager.get_surrounding_unit_by_guid( world_session.player_mgr, guid) if not flight_master: return 0 result = ActivateTaxiReplies.ERR_TAXIOK if world_session.player_mgr.in_combat: result = ActivateTaxiReplies.ERR_TAXIPLAYERBUSY elif world_session.player_mgr.mount_display_id > 0: result = ActivateTaxiReplies.ERR_TAXIPLAYERALREADYMOUNTED taxi_path = DbcDatabaseManager.taxi_path_get(start_node, dest_node) if not taxi_path: result = ActivateTaxiReplies.ERR_TAXINOSUCHPATH if world_session.player_mgr.coinage < taxi_path.Cost: result = ActivateTaxiReplies.ERR_TAXINOTENOUGHMONEY data = pack('<I', result) world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_ACTIVATETAXIREPLY, data)) if result == ActivateTaxiReplies.ERR_TAXIOK: world_session.player_mgr.mod_money(-taxi_path.Cost) world_session.player_mgr.taxi_manager.begin_taxi_flight( taxi_path, start_node, dest_node, flight_master=flight_master) return 0
def _get_default_spells(self) -> list[int]: creature_family = self.creature_template.beast_family if not creature_family: return [] family_entry = DbcDatabaseManager.CreatureFamilyHolder.creature_family_get_by_id( creature_family) skill_lines = [family_entry.SkillLine_1, family_entry.SkillLine_2 ] # TODO 2 is pet talents or 0, ignore for now. if not skill_lines[0]: return [] skill_line_abilities = DbcDatabaseManager.skill_line_ability_get_by_skill_lines( [skill_lines[0]]) if not skill_line_abilities: return [] # TODO Just returning highest ranks for now. return [ skill_line_ability.Spell for skill_line_ability in skill_line_abilities if not skill_line_ability.SupercededBySpell ]