aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2008-11-20 10:43:20 -0600
committermegamage <none@none>2008-11-20 10:43:20 -0600
commit85d28160134fc81d28304ffd3361a589a96b848a (patch)
tree778c3ab2a3cdd1c51d550abc23533e382f59f5a2
parent0b61584e1b19afb8dbef376a4e2903d8631bfc1d (diff)
*DB script table stucture change. Source Mangos. Also fix some bugs. Hopefully this rev will make program usable again.
--HG-- branch : trunk
-rw-r--r--sql/updates/262_characters.sql5
-rw-r--r--sql/updates/262_realmd.sql2
-rw-r--r--sql/updates/262_world.sql70
-rw-r--r--sql/updates/262_world_runthisonlyonce.sql31
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp94
-rw-r--r--src/bindings/scripts/ScriptMgr.h59
-rw-r--r--src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp2
-rw-r--r--src/bindings/scripts/scripts/boss/boss_emeriss.cpp2
-rw-r--r--src/bindings/scripts/scripts/boss/boss_taerar.cpp4
-rw-r--r--src/bindings/scripts/scripts/boss/boss_ysondre.cpp4
-rw-r--r--src/bindings/scripts/scripts/creature/mob_event_ai.cpp2
-rw-r--r--src/bindings/scripts/scripts/creature/mob_generic_creature.cpp2
-rw-r--r--src/bindings/scripts/scripts/custom/custom_example.cpp2
-rw-r--r--src/bindings/scripts/scripts/custom/custom_gossip_codebox.cpp2
-rw-r--r--src/bindings/scripts/scripts/custom/test.cpp2
-rw-r--r--src/bindings/scripts/scripts/go/go_scripts.cpp18
-rw-r--r--src/bindings/scripts/scripts/guard/guards.cpp40
-rw-r--r--src/bindings/scripts/scripts/item/item_scripts.cpp38
-rw-r--r--src/bindings/scripts/scripts/item/item_test.cpp2
-rw-r--r--src/bindings/scripts/scripts/npc/npc_innkeeper.cpp2
-rw-r--r--src/bindings/scripts/scripts/npc/npc_professions.cpp10
-rw-r--r--src/bindings/scripts/scripts/npc/npcs_special.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/azshara/azshara.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_angerrel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_doomrel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_doperel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_general_angerforge.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_gloomrel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_haterel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_seethrel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_depths/boss_vilerel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_highlord_omokk.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_rend_blackhand.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_the_beast.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackrock_spire/boss_warmaster_voone.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_victor_nefarius.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/felwood/felwood.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/feralas/feralas.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_shade_of_aran.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp22
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp18
-rw-r--r--src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp24
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_celebras_the_cursed.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_baron_geddon.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_majordomo_executus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/boss_sulfuron_harbinger.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/instance_molten_core.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_highlord_mograine.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_lady_blaumeux.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_sir_zeliek.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_thane_korthazz.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_whitemane.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scarlet_commander_mograine.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_death_knight_darkreaver.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_lord_alexei_barov.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp26
-rw-r--r--src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/silithus/silithus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_cannon_master_willey.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_maleki_the_pallid.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_order_of_silver_hand.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_ramstein_the_gorger.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_timmy_the_cruel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/the_eye.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/undercity/undercity.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/westfall/westfall.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp18
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp10
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp2
-rw-r--r--src/game/ArenaTeam.cpp1592
-rw-r--r--src/game/AuctionHouse.cpp12
-rw-r--r--src/game/Bag.cpp13
-rw-r--r--src/game/Chat.cpp36
-rw-r--r--src/game/Chat.h14
-rw-r--r--src/game/Creature.cpp21
-rw-r--r--src/game/Creature.h17
-rw-r--r--src/game/CreatureAI.cpp4
-rw-r--r--src/game/CreatureAIImpl.h4
-rw-r--r--src/game/CreatureAIRegistry.cpp4
-rw-r--r--src/game/CreatureAISelector.cpp4
-rw-r--r--src/game/Formulas.h415
-rw-r--r--src/game/GMTicketHandler.cpp358
-rw-r--r--src/game/GMTicketMgr.h243
-rw-r--r--src/game/GameObject.h6
-rw-r--r--src/game/Item.cpp25
-rw-r--r--src/game/Item.h5
-rw-r--r--src/game/ItemEnchantmentMgr.cpp4
-rw-r--r--src/game/ItemEnchantmentMgr.h4
-rw-r--r--src/game/ItemHandler.cpp31
-rw-r--r--src/game/ItemPrototype.h40
-rw-r--r--src/game/Level2.cpp8532
-rw-r--r--src/game/Level3.cpp150
-rw-r--r--src/game/Mail.cpp15
-rw-r--r--src/game/Map.cpp6
-rw-r--r--src/game/Map.h9
-rw-r--r--src/game/MapManager.cpp2
-rw-r--r--src/game/MapManager.h7
-rw-r--r--src/game/ObjectMgr.cpp14866
-rw-r--r--src/game/ObjectMgr.h1851
-rw-r--r--src/game/PlayerDump.cpp1265
-rw-r--r--src/game/SpellHandler.cpp15
-rw-r--r--src/game/WaypointManager.cpp588
-rw-r--r--src/game/WaypointManager.h183
-rw-r--r--src/game/WaypointMovementGenerator.cpp1305
-rw-r--r--src/game/World.cpp63
-rw-r--r--src/game/World.h79
-rw-r--r--src/shared/Database/DBCEnums.h104
-rw-r--r--src/shared/Database/DBCStores.cpp35
-rw-r--r--src/shared/Database/DBCStores.h5
-rw-r--r--src/shared/Database/DBCStructure.h119
-rw-r--r--src/shared/Database/SQLStorage.cpp160
-rw-r--r--src/shared/Database/SQLStorage.h68
-rw-r--r--src/shared/Database/SQLStorageImpl.h214
-rw-r--r--src/shared/Database/dbcfile.cpp4
-rw-r--r--src/shared/Database/dbcfile.h4
-rw-r--r--src/shared/ProgressBar.cpp4
-rw-r--r--src/shared/ProgressBar.h4
-rw-r--r--src/trinitycore/CliRunnable.cpp10
-rw-r--r--src/trinitycore/Master.cpp16
-rw-r--r--src/trinitycore/WorldRunnable.cpp2
360 files changed, 17339 insertions, 16753 deletions
diff --git a/sql/updates/262_characters.sql b/sql/updates/262_characters.sql
new file mode 100644
index 00000000000..9e9fbc1caf7
--- /dev/null
+++ b/sql/updates/262_characters.sql
@@ -0,0 +1,5 @@
+ALTER TABLE `guild_bank_tab`
+ CHANGE COLUMN `TabText` `TabText` text;
+
+ALTER TABLE `character_aura` ADD `stackcount` INT NOT NULL DEFAULT '1' AFTER `effect_index` ;
+ALTER TABLE `pet_aura` ADD `stackcount` INT NOT NULL DEFAULT '1' AFTER `effect_index` ; \ No newline at end of file
diff --git a/sql/updates/262_realmd.sql b/sql/updates/262_realmd.sql
new file mode 100644
index 00000000000..62e5c050c4a
--- /dev/null
+++ b/sql/updates/262_realmd.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `account`
+ CHANGE COLUMN `email` `email` text; \ No newline at end of file
diff --git a/sql/updates/262_world.sql b/sql/updates/262_world.sql
new file mode 100644
index 00000000000..8e9d8b47687
--- /dev/null
+++ b/sql/updates/262_world.sql
@@ -0,0 +1,70 @@
+DELETE FROM trinity_string WHERE entry IN (1119,1120,1121);
+
+INSERT INTO trinity_string VALUES
+(1119,'You must use male or female as gender.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(1120,'You change gender of %s to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(1121,'Your gender changed to %s by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+
+
+DELETE FROM command WHERE name IN ('modify gender');
+
+INSERT INTO command VALUES
+('modify gender',2,'Syntax: .modify gender male/female\r\n\r\nChange gender of selected player.');
+
+
+delete from `command` where `name` IN ('senditems','sendmail');
+insert into `command` (`name`, `security`, `help`) values
+('senditems',3,'Syntax: .senditems #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'),
+('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text"\r\n\r\nSend a mail to a player. Subject and mail text must be in "".');
+
+
+delete from `command` where `name` = 'sendmoney';
+insert into `command` (`name`, `security`, `help`) values
+('sendmoney',3,'Syntax: .sendmoney #playername "#subject" "#text" #money\r\n\r\nSend mail with money to a player. Subject and mail text must be in "".');
+
+
+DELETE FROM trinity_string WHERE entry IN (453);
+
+
+DROP TABLE IF EXISTS `db_script_string`;
+CREATE TABLE `db_script_string` (
+ `entry` int(11) unsigned NOT NULL default '0',
+ `content_default` text NOT NULL,
+ `content_loc1` text,
+ `content_loc2` text,
+ `content_loc3` text,
+ `content_loc4` text,
+ `content_loc5` text,
+ `content_loc6` text,
+ `content_loc7` text,
+ `content_loc8` text,
+ PRIMARY KEY (`entry`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+
+DELETE FROM `command` WHERE `name` IN (
+ 'server exit',
+ 'server idleshutdown',
+ 'server idleshutdown cancel',
+ 'server idlerestart',
+ 'server idlerestart cancel',
+ 'server restart',
+ 'server restart cancel',
+ 'server shutdown',
+ 'server shutdown cancel'
+);
+
+INSERT INTO `command` (`name`, `security`, `help`) VALUES
+('server exit',4,'Syntax: .server exit\r\n\r\nTerminate mangosd NOW. Exit code 0.'),
+('server idleshutdown',3,'Syntax: .server idleshutdown #delay [#exist_code]\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players). Use #exist_code or 0 as program exist code.'),
+('server idleshutdown cancel',3,'Syntax: .server idleshutdown cancel\r\n\r\nCancel the restart/shutdown timer if any.'),
+('server idlerestart',3,'Syntax: .server idlerestart #delay\r\n\r\nRestart the server after #delay seconds if no active connections are present (no players). Use #exist_code or 2 as program exist code.'),
+('server idlerestart cancel',3,'Syntax: .server idlerestart cancel\r\n\r\nCancel the restart/shutdown timer if any.'),
+('server restart',3,'Syntax: .server restart #delay\r\n\r\nRestart the server after #delay seconds. Use #exist_code or 2 as program exist code.'),
+('server restart cancel',3,'Syntax: .server restart cancel\r\n\r\nCancel the restart/shutdown timer if any.'),
+('server shutdown',3,'Syntax: .server shutdown #delay [#exist_code]\r\n\r\nShut the server down after #delay seconds. Use #exist_code or 0 as program exist code.'),
+('server shutdown cancel',3,'Syntax: .server shutdown cancel\r\n\r\nCancel the restart/shutdown timer if any.');
+
+DELETE FROM trinity_string WHERE entry IN (251);
+INSERT INTO trinity_string VALUES
+(251,'Text%d (ID: %i): %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); \ No newline at end of file
diff --git a/sql/updates/262_world_runthisonlyonce.sql b/sql/updates/262_world_runthisonlyonce.sql
new file mode 100644
index 00000000000..31926c3a4d1
--- /dev/null
+++ b/sql/updates/262_world_runthisonlyonce.sql
@@ -0,0 +1,31 @@
+ALTER TABLE event_scripts
+ DROP datatext,
+ ADD COLUMN dataint int(11) NOT NULL default '0' AFTER datalong2;
+
+ALTER TABLE gameobject_scripts
+ DROP datatext,
+ ADD COLUMN dataint int(11) NOT NULL default '0' AFTER datalong2;
+
+ALTER TABLE quest_end_scripts
+ DROP datatext,
+ ADD COLUMN dataint int(11) NOT NULL default '0' AFTER datalong2;
+
+ALTER TABLE quest_start_scripts
+ DROP datatext,
+ ADD COLUMN dataint int(11) NOT NULL default '0' AFTER datalong2;
+
+ALTER TABLE spell_scripts
+ DROP datatext,
+ ADD COLUMN dataint int(11) NOT NULL default '0' AFTER datalong2;
+
+ALTER TABLE creature_movement
+ DROP `text1`,
+ DROP `text2`,
+ DROP `text3`,
+ DROP `text4`,
+ DROP `text5`,
+ ADD COLUMN textid1 int(11) NOT NULL default '0' AFTER waittime,
+ ADD COLUMN textid2 int(11) NOT NULL default '0' AFTER textid1,
+ ADD COLUMN textid3 int(11) NOT NULL default '0' AFTER textid2,
+ ADD COLUMN textid4 int(11) NOT NULL default '0' AFTER textid3,
+ ADD COLUMN textid5 int(11) NOT NULL default '0' AFTER textid4; \ No newline at end of file
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index 840cdc4be60..ad6bcf76c08 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -17,7 +17,8 @@
#endif _TRINITY_SCRIPT_CONFIG
//*** Global data ***
-int nrscripts;
+int num_db_scripts;
+int num_sc_scripts;
Script *m_scripts[MAX_SCRIPTS];
DatabaseType TScriptDB;
@@ -47,7 +48,6 @@ enum ChatType
// Text Maps
UNORDERED_MAP<int32, StringTextData> TextMap;
-
//*** End Global data ***
//*** EventAI data ***
@@ -1180,15 +1180,16 @@ struct TSpellSummary {
TRINITY_DLL_EXPORT
void ScriptsFree()
-{
+{
// Free Spell Summary
delete []SpellSummary;
// Free resources before library unload
- for(int i=0;i<nrscripts;i++)
+ for(int i=0;i<num_db_scripts;i++)
delete m_scripts[i];
- nrscripts = 0;
+ num_db_scripts = 0;
+ num_sc_scripts = 0;
}
TRINITY_DLL_EXPORT
@@ -1239,12 +1240,13 @@ void ScriptsInit()
if (CanLoadDB)
LoadDatabase();
+ num_db_scripts = GetScriptNames().size();
+
outstring_log("TSCR: Loading C++ scripts");
barGoLink bar(1);
bar.step();
outstring_log("");
- nrscripts = 0;
for(int i=0;i<MAX_SCRIPTS;i++)
m_scripts[i]=NULL;
@@ -1775,8 +1777,7 @@ void ScriptsInit()
// -------------------
- outstring_log("TSCR: Loaded %u C++ Scripts", nrscripts);
- outstring_log("");
+ outstring_log(">> Loaded %i C++ Scripts (of %i ScriptNames defined in Mangos database)", num_sc_scripts, num_db_scripts);
}
//*********************************
@@ -1848,32 +1849,29 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
//*********************************
//*** Functions used internally ***
-TRINITY_DLL_EXPORT
-char const* ScriptsVersion()
+void Script::RegisterSelf()
{
- return "Default Trinity scripting library";
-}
-
-Script* GetScriptByName(std::string Name)
-{
- if (Name.empty())
- return NULL;
-
- for(int i=0;i<MAX_SCRIPTS;i++)
+ int id = GetScriptId(Name.c_str());
+ if (id != 0)
{
- if (m_scripts[i] && m_scripts[i]->Name == Name)
- return m_scripts[i];
- }
- return NULL;
+ m_scripts[id] = this;
+ ++num_sc_scripts;
+ } else
+ debug_log("SD2: RegisterSelf, but script named %s does not have ScriptName assigned in database.",(this)->Name.c_str());
}
//********************************
//*** Functions to be Exported ***
TRINITY_DLL_EXPORT
+char const* ScriptsVersion()
+{
+ return "Default Trinity scripting library";
+}
+TRINITY_DLL_EXPORT
bool GossipHello ( Player * player, Creature *_Creature )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pGossipHello) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1885,7 +1883,7 @@ bool GossipSelect( Player *player, Creature *_Creature, uint32 sender, uint32 ac
{
debug_log("TSCR: Gossip selection, sender: %d, action: %d",sender, action);
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pGossipSelect) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1897,7 +1895,7 @@ bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, u
{
debug_log("TSCR: Gossip selection with code, sender: %d, action: %d",sender, action);
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pGossipSelectWithCode) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1907,7 +1905,7 @@ bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, u
TRINITY_DLL_EXPORT
bool QuestAccept( Player *player, Creature *_Creature, Quest const *_Quest )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pQuestAccept) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1917,7 +1915,7 @@ bool QuestAccept( Player *player, Creature *_Creature, Quest const *_Quest )
TRINITY_DLL_EXPORT
bool QuestSelect( Player *player, Creature *_Creature, Quest const *_Quest )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pQuestSelect) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1927,7 +1925,7 @@ bool QuestSelect( Player *player, Creature *_Creature, Quest const *_Quest )
TRINITY_DLL_EXPORT
bool QuestComplete( Player *player, Creature *_Creature, Quest const *_Quest )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pQuestComplete) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1937,7 +1935,7 @@ bool QuestComplete( Player *player, Creature *_Creature, Quest const *_Quest )
TRINITY_DLL_EXPORT
bool ChooseReward( Player *player, Creature *_Creature, Quest const *_Quest, uint32 opt )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pChooseReward) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1947,7 +1945,7 @@ bool ChooseReward( Player *player, Creature *_Creature, Quest const *_Quest, uin
TRINITY_DLL_EXPORT
uint32 NPCDialogStatus( Player *player, Creature *_Creature )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pNPCDialogStatus) return 100;
player->PlayerTalkClass->ClearMenus();
@@ -1957,8 +1955,8 @@ uint32 NPCDialogStatus( Player *player, Creature *_Creature )
TRINITY_DLL_EXPORT
uint32 GODialogStatus( Player *player, GameObject *_GO )
{
- Script *tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
- if(!tmpscript || !tmpscript->pGODialogStatus) return 100;
+ Script *tmpscript = m_scripts[_GO->GetGOInfo()->ScriptId];
+ if (!tmpscript || !tmpscript->pGODialogStatus) return 100;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGODialogStatus(player,_GO);
@@ -1967,7 +1965,7 @@ uint32 GODialogStatus( Player *player, GameObject *_GO )
TRINITY_DLL_EXPORT
bool ItemHello( Player *player, Item *_Item, Quest const *_Quest )
{
- Script *tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
+ Script *tmpscript = m_scripts[_Item->GetProto()->ScriptId];
if (!tmpscript || !tmpscript->pItemHello) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1977,7 +1975,7 @@ bool ItemHello( Player *player, Item *_Item, Quest const *_Quest )
TRINITY_DLL_EXPORT
bool ItemQuestAccept( Player *player, Item *_Item, Quest const *_Quest )
{
- Script *tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
+ Script *tmpscript = m_scripts[_Item->GetProto()->ScriptId];
if (!tmpscript || !tmpscript->pItemQuestAccept) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1987,7 +1985,7 @@ bool ItemQuestAccept( Player *player, Item *_Item, Quest const *_Quest )
TRINITY_DLL_EXPORT
bool GOHello( Player *player, GameObject *_GO )
{
- Script *tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
+ Script *tmpscript = m_scripts[_GO->GetGOInfo()->ScriptId];
if (!tmpscript || !tmpscript->pGOHello) return false;
player->PlayerTalkClass->ClearMenus();
@@ -1997,7 +1995,7 @@ bool GOHello( Player *player, GameObject *_GO )
TRINITY_DLL_EXPORT
bool GOQuestAccept( Player *player, GameObject *_GO, Quest const *_Quest )
{
- Script *tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
+ Script *tmpscript = m_scripts[_GO->GetGOInfo()->ScriptId];
if (!tmpscript || !tmpscript->pGOQuestAccept) return false;
player->PlayerTalkClass->ClearMenus();
@@ -2007,7 +2005,7 @@ bool GOQuestAccept( Player *player, GameObject *_GO, Quest const *_Quest )
TRINITY_DLL_EXPORT
bool GOChooseReward( Player *player, GameObject *_GO, Quest const *_Quest, uint32 opt )
{
- Script *tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
+ Script *tmpscript = m_scripts[_GO->GetGOInfo()->ScriptId];
if (!tmpscript || !tmpscript->pGOChooseReward) return false;
player->PlayerTalkClass->ClearMenus();
@@ -2017,9 +2015,7 @@ bool GOChooseReward( Player *player, GameObject *_GO, Quest const *_Quest, uint3
TRINITY_DLL_EXPORT
bool AreaTrigger( Player *player, AreaTriggerEntry * atEntry)
{
- Script *tmpscript = NULL;
-
- tmpscript = GetScriptByName(GetAreaTriggerScriptNameById(atEntry->id));
+ Script *tmpscript = m_scripts[GetAreaTriggerScriptId(atEntry->id)];
if (!tmpscript || !tmpscript->pAreaTrigger) return false;
return tmpscript->pAreaTrigger(player, atEntry);
@@ -2028,16 +2024,16 @@ bool AreaTrigger( Player *player, AreaTriggerEntry * atEntry)
TRINITY_DLL_EXPORT
CreatureAI* GetAI(Creature *_Creature)
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
-
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->GetAI) return NULL;
+
return tmpscript->GetAI(_Creature);
}
TRINITY_DLL_EXPORT
bool ItemUse( Player *player, Item* _Item, SpellCastTargets const& targets)
{
- Script *tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
+ Script *tmpscript = m_scripts[_Item->GetProto()->ScriptId];
if (!tmpscript || !tmpscript->pItemUse) return false;
return tmpscript->pItemUse(player,_Item,targets);
@@ -2046,7 +2042,7 @@ bool ItemUse( Player *player, Item* _Item, SpellCastTargets const& targets)
TRINITY_DLL_EXPORT
bool ReceiveEmote( Player *player, Creature *_Creature, uint32 emote )
{
- Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
+ Script *tmpscript = m_scripts[_Creature->GetScriptId()];
if (!tmpscript || !tmpscript->pReceiveEmote) return false;
return tmpscript->pReceiveEmote(player, _Creature, emote);
@@ -2055,12 +2051,10 @@ bool ReceiveEmote( Player *player, Creature *_Creature, uint32 emote )
TRINITY_DLL_EXPORT
InstanceData* CreateInstanceData(Map *map)
{
- Script *tmpscript = NULL;
-
- if (!map->IsDungeon()) return false;
+ if (!map->IsDungeon()) return NULL;
- tmpscript = GetScriptByName(((InstanceMap*)map)->GetScript());
- if (!tmpscript || !tmpscript->GetInstanceData) return false;
+ Script *tmpscript = m_scripts[((InstanceMap*)map)->GetScriptId()];
+ if (!tmpscript || !tmpscript->GetInstanceData) return NULL;
return tmpscript->GetInstanceData(map);
}
diff --git a/src/bindings/scripts/ScriptMgr.h b/src/bindings/scripts/ScriptMgr.h
index 83b2c0dd7a0..ef7bdfd3cce 100644
--- a/src/bindings/scripts/ScriptMgr.h
+++ b/src/bindings/scripts/ScriptMgr.h
@@ -24,46 +24,45 @@ class Map;
class Unit;
class WorldObject;
-#define MAX_SCRIPTS 1000 //72 bytes each (approx 71kb)
+#define MAX_SCRIPTS 5000 //72 bytes each (approx 351kb)
#define VISIBLE_RANGE (166.0f) //MAX visible range (size of grid)
#define DEFAULT_TEXT "<Trinity Script Text Entry Missing!>"
struct Script
{
Script() :
-pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
-pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
-pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
-pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL), GetInstanceData(NULL)
-{}
+ pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
+ pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
+ pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
+ pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL), GetInstanceData(NULL)
+ {}
-std::string Name;
+ std::string Name;
-// Quest/gossip Methods to be scripted
-bool (*pGossipHello )(Player*, Creature*);
-bool (*pQuestAccept )(Player*, Creature*, Quest const* );
-bool (*pGossipSelect )(Player*, Creature*, uint32 , uint32 );
-bool (*pGossipSelectWithCode)(Player*, Creature*, uint32 , uint32 , const char* );
-bool (*pQuestSelect )(Player*, Creature*, Quest const* );
-bool (*pQuestComplete )(Player*, Creature*, Quest const* );
-uint32 (*pNPCDialogStatus )(Player*, Creature* );
-uint32 (*pGODialogStatus )(Player *player, GameObject * _GO );
-bool (*pChooseReward )(Player*, Creature*, Quest const*, uint32 );
-bool (*pItemHello )(Player*, Item*, Quest const* );
-bool (*pGOHello )(Player*, GameObject* );
-bool (*pAreaTrigger )(Player*, AreaTriggerEntry* );
-bool (*pItemQuestAccept )(Player*, Item *, Quest const* );
-bool (*pGOQuestAccept )(Player*, GameObject*, Quest const* );
-bool (*pGOChooseReward )(Player*, GameObject*_GO, Quest const*, uint32 );
-bool (*pReceiveEmote )(Player*, Creature*, uint32 );
-bool (*pItemUse )(Player*, Item*, SpellCastTargets const& );
+ //Methods to be scripted
+ bool (*pGossipHello )(Player*, Creature*);
+ bool (*pQuestAccept )(Player*, Creature*, Quest const* );
+ bool (*pGossipSelect )(Player*, Creature*, uint32 , uint32 );
+ bool (*pGossipSelectWithCode)(Player*, Creature*, uint32 , uint32 , const char* );
+ bool (*pQuestSelect )(Player*, Creature*, Quest const* );
+ bool (*pQuestComplete )(Player*, Creature*, Quest const* );
+ uint32 (*pNPCDialogStatus )(Player*, Creature* );
+ uint32 (*pGODialogStatus )(Player*, GameObject * _GO );
+ bool (*pChooseReward )(Player*, Creature*, Quest const*, uint32 );
+ bool (*pItemHello )(Player*, Item*, Quest const* );
+ bool (*pGOHello )(Player*, GameObject* );
+ bool (*pAreaTrigger )(Player*, AreaTriggerEntry* );
+ bool (*pItemQuestAccept )(Player*, Item *, Quest const* );
+ bool (*pGOQuestAccept )(Player*, GameObject*, Quest const* );
+ bool (*pGOChooseReward )(Player*, GameObject*, Quest const*, uint32 );
+ bool (*pReceiveEmote )(Player*, Creature*, uint32 );
+ bool (*pItemUse )(Player*, Item*, SpellCastTargets const& );
-CreatureAI* (*GetAI)(Creature*);
-InstanceData* (*GetInstanceData)(Map*);
-};
+ CreatureAI* (*GetAI)(Creature*);
+ InstanceData* (*GetInstanceData)(Map*);
-extern int nrscripts;
-extern Script *m_scripts[MAX_SCRIPTS];
+ void RegisterSelf();
+};
//Generic scripting text function
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target = NULL);
diff --git a/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp b/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp
index 117121d8530..83dda669e1f 100644
--- a/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp
+++ b/src/bindings/scripts/scripts/areatrigger/areatrigger_scripts.cpp
@@ -40,5 +40,5 @@ void AddSC_areatrigger_scripts()
newscript = new Script;
newscript->Name="at_test";
newscript->pAreaTrigger = ATtest;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/boss/boss_emeriss.cpp b/src/bindings/scripts/scripts/boss/boss_emeriss.cpp
index 99b3a845f95..a8af2b43e41 100644
--- a/src/bindings/scripts/scripts/boss/boss_emeriss.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_emeriss.cpp
@@ -152,5 +152,5 @@ void AddSC_boss_emeriss()
newscript = new Script;
newscript->Name="boss_emeriss";
newscript->GetAI = GetAI_boss_emeriss;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/boss/boss_taerar.cpp b/src/bindings/scripts/scripts/boss/boss_taerar.cpp
index 67d3364dd66..faed723cb4d 100644
--- a/src/bindings/scripts/scripts/boss/boss_taerar.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_taerar.cpp
@@ -297,10 +297,10 @@ void AddSC_boss_taerar()
newscript = new Script;
newscript->Name="boss_taerar";
newscript->GetAI = GetAI_boss_taerar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_shade_of_taerar";
newscript->GetAI = GetAI_boss_shadeoftaerar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/boss/boss_ysondre.cpp b/src/bindings/scripts/scripts/boss/boss_ysondre.cpp
index 3df1746bd76..b9fad649d71 100644
--- a/src/bindings/scripts/scripts/boss/boss_ysondre.cpp
+++ b/src/bindings/scripts/scripts/boss/boss_ysondre.cpp
@@ -237,10 +237,10 @@ void AddSC_boss_ysondre()
newscript = new Script;
newscript->Name="boss_ysondre";
newscript->GetAI = GetAI_boss_ysondre;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_dementeddruids";
newscript->GetAI = GetAI_mob_dementeddruids;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
index d7578731e91..af945282935 100644
--- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
@@ -1400,5 +1400,5 @@ void AddSC_mob_event()
newscript = new Script;
newscript->Name="mob_eventai";
newscript->GetAI = GetAI_Mob_EventAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp
index 0e03915df0e..02e34a8fa1e 100644
--- a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp
@@ -168,5 +168,5 @@ void AddSC_generic_creature()
newscript = new Script;
newscript->Name="generic_creature";
newscript->GetAI = GetAI_generic_creature;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/custom/custom_example.cpp b/src/bindings/scripts/scripts/custom/custom_example.cpp
index 133b2136a1c..d1a30fd06af 100644
--- a/src/bindings/scripts/scripts/custom/custom_example.cpp
+++ b/src/bindings/scripts/scripts/custom/custom_example.cpp
@@ -273,5 +273,5 @@ void AddSC_custom_example()
newscript->pGossipHello = &GossipHello_custom_example;
newscript->pGossipSelect = &GossipSelect_custom_example;
newscript->pReceiveEmote = &ReceiveEmote_custom_example;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/custom/custom_gossip_codebox.cpp b/src/bindings/scripts/scripts/custom/custom_gossip_codebox.cpp
index c8cfe711fc9..3963d31b98b 100644
--- a/src/bindings/scripts/scripts/custom/custom_gossip_codebox.cpp
+++ b/src/bindings/scripts/scripts/custom/custom_gossip_codebox.cpp
@@ -77,5 +77,5 @@ void AddSC_custom_gossip_codebox()
newscript->pGossipHello = &GossipHello_custom_gossip_codebox;
newscript->pGossipSelect = &GossipSelect_custom_gossip_codebox;
newscript->pGossipSelectWithCode = &GossipSelectWithCode_custom_gossip_codebox;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/custom/test.cpp b/src/bindings/scripts/scripts/custom/test.cpp
index 52d5c7d6f4f..e54716afcf0 100644
--- a/src/bindings/scripts/scripts/custom/test.cpp
+++ b/src/bindings/scripts/scripts/custom/test.cpp
@@ -196,5 +196,5 @@ void AddSC_test()
newscript->GetAI = GetAI_test;
newscript->pGossipHello = &GossipHello_npc_test;
newscript->pGossipSelect = &GossipSelect_npc_test;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/go/go_scripts.cpp b/src/bindings/scripts/scripts/go/go_scripts.cpp
index a06e588d916..511e283373a 100644
--- a/src/bindings/scripts/scripts/go/go_scripts.cpp
+++ b/src/bindings/scripts/scripts/go/go_scripts.cpp
@@ -165,45 +165,45 @@ void AddSC_go_scripts()
newscript = new Script;
newscript->Name="go_northern_crystal_pylon";
newscript->pGOHello = &GOHello_go_northern_crystal_pylon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_eastern_crystal_pylon";
newscript->pGOHello = &GOHello_go_eastern_crystal_pylon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_western_crystal_pylon";
newscript->pGOHello = &GOHello_go_western_crystal_pylon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_barov_journal";
newscript->pGOHello = &GOHello_go_barov_journal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_field_repair_bot_74A";
newscript->pGOHello = &GOHello_go_field_repair_bot_74A;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_orb_of_command";
newscript->pGOHello = &GOHello_go_orb_of_command;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_tablet_of_madness";
newscript->pGOHello = &GOHello_go_tablet_of_madness;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_tablet_of_the_seven";
newscript->pGOHello = &GOHello_go_tablet_of_the_seven;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_teleporter";
newscript->pGOHello = &GOHello_go_teleporter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/guard/guards.cpp b/src/bindings/scripts/scripts/guard/guards.cpp
index fdc541665d1..a96ded0ac70 100644
--- a/src/bindings/scripts/scripts/guard/guards.cpp
+++ b/src/bindings/scripts/scripts/guard/guards.cpp
@@ -3980,75 +3980,75 @@ void AddSC_guards()
newscript->pGossipHello = &GossipHello_guard_azuremyst;
newscript->pGossipSelect = &GossipSelect_guard_azuremyst;
newscript->GetAI = GetAI_guard_azuremyst;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_bluffwatcher";
newscript->pGossipHello = &GossipHello_guard_bluffwatcher;
newscript->pGossipSelect = &GossipSelect_guard_bluffwatcher;
newscript->GetAI = GetAI_guard_bluffwatcher;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_contested";
newscript->GetAI = GetAI_guard_contested;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_darnassus";
newscript->pGossipHello = &GossipHello_guard_darnassus;
newscript->pGossipSelect = &GossipSelect_guard_darnassus;
newscript->GetAI = GetAI_guard_darnassus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_dunmorogh";
newscript->pGossipHello = &GossipHello_guard_dunmorogh;
newscript->pGossipSelect = &GossipSelect_guard_dunmorogh;
newscript->GetAI = GetAI_guard_dunmorogh;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_durotar";
newscript->pGossipHello = &GossipHello_guard_durotar;
newscript->pGossipSelect = &GossipSelect_guard_durotar;
newscript->GetAI = GetAI_guard_durotar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_elwynnforest";
newscript->pGossipHello = &GossipHello_guard_elwynnforest;
newscript->pGossipSelect = &GossipSelect_guard_elwynnforest;
newscript->GetAI = GetAI_guard_elwynnforest;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_eversong";
newscript->pGossipHello = &GossipHello_guard_eversong;
newscript->pGossipSelect = &GossipSelect_guard_eversong;
newscript->GetAI = GetAI_guard_eversong;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_exodar";
newscript->pGossipHello = &GossipHello_guard_exodar;
newscript->pGossipSelect = &GossipSelect_guard_exodar;
newscript->GetAI = GetAI_guard_exodar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_ironforge";
newscript->pGossipHello = &GossipHello_guard_ironforge;
newscript->pGossipSelect = &GossipSelect_guard_ironforge;
newscript->GetAI = GetAI_guard_ironforge;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_mulgore";
newscript->pGossipHello = &GossipHello_guard_mulgore;
newscript->pGossipSelect = &GossipSelect_guard_mulgore;
newscript->GetAI = GetAI_guard_mulgore;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_orgrimmar";
@@ -4056,35 +4056,35 @@ void AddSC_guards()
newscript->pGossipSelect = &GossipSelect_guard_orgrimmar;
newscript->pReceiveEmote = &ReceiveEmote_guard_orgrimmar;
newscript->GetAI = GetAI_guard_orgrimmar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_shattrath";
newscript->pGossipHello = &GossipHello_guard_shattrath;
newscript->pGossipSelect = &GossipSelect_guard_shattrath;
newscript->GetAI = GetAI_guard_shattrath;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_shattrath_aldor";
newscript->GetAI = GetAI_guard_shattrath_aldor;
newscript->pGossipHello = &GossipHello_guard_shattrath_aldor;
newscript->pGossipSelect = &GossipSelect_guard_shattrath_aldor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_shattrath_scryer";
newscript->GetAI = GetAI_guard_shattrath_scryer;
newscript->pGossipHello = &GossipHello_guard_shattrath_scryer;
newscript->pGossipSelect = &GossipSelect_guard_shattrath_scryer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_silvermoon";
newscript->pGossipHello = &GossipHello_guard_silvermoon;
newscript->pGossipSelect = &GossipSelect_guard_silvermoon;
newscript->GetAI = GetAI_guard_silvermoon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_stormwind";
@@ -4092,26 +4092,26 @@ void AddSC_guards()
newscript->pGossipSelect = &GossipSelect_guard_stormwind;
newscript->pReceiveEmote = &ReceiveEmote_guard_stormwind;
newscript->GetAI = GetAI_guard_stormwind;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_teldrassil";
newscript->pGossipHello = &GossipHello_guard_teldrassil;
newscript->pGossipSelect = &GossipSelect_guard_teldrassil;
newscript->GetAI = GetAI_guard_teldrassil;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_tirisfal";
newscript->pGossipHello = &GossipHello_guard_tirisfal;
newscript->pGossipSelect = &GossipSelect_guard_tirisfal;
newscript->GetAI = GetAI_guard_tirisfal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="guard_undercity";
newscript->pGossipHello = &GossipHello_guard_undercity;
newscript->pGossipSelect = &GossipSelect_guard_undercity;
newscript->GetAI = GetAI_guard_undercity;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/item/item_scripts.cpp b/src/bindings/scripts/scripts/item/item_scripts.cpp
index 42ab5914262..372f438753c 100644
--- a/src/bindings/scripts/scripts/item/item_scripts.cpp
+++ b/src/bindings/scripts/scripts/item/item_scripts.cpp
@@ -455,95 +455,95 @@ void AddSC_item_scripts()
newscript = new Script;
newscript->Name="item_area_52_special";
newscript->pItemUse = ItemUse_item_area_52_special;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_arcane_charges";
newscript->pItemUse = ItemUse_item_arcane_charges;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_attuned_crystal_cores";
newscript->pItemUse = ItemUse_item_attuned_crystal_cores;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_blackwhelp_net";
newscript->pItemUse = ItemUse_item_blackwhelp_net;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_disciplinary_rod";
newscript->pItemUse = ItemUse_item_disciplinary_rod;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_draenei_fishing_net";
newscript->pItemUse = ItemUse_item_draenei_fishing_net;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_nether_wraith_beacon";
newscript->pItemUse = ItemUse_item_nether_wraith_beacon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_flying_machine";
newscript->pItemUse = ItemUse_item_flying_machine;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_gor_dreks_ointment";
newscript->pItemUse = ItemUse_item_gor_dreks_ointment;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_muiseks_vessel";
newscript->pItemUse = ItemUse_item_muiseks_vessel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_razorthorn_flayer_gland";
newscript->pItemUse = ItemUse_item_razorthorn_flayer_gland;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_tame_beast_rods";
newscript->pItemUse = ItemUse_item_tame_beast_rods;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_protovoltaic_magneto_collector";
newscript->pItemUse = ItemUse_item_protovoltaic_magneto_collector;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_soul_cannon";
newscript->pItemUse = ItemUse_item_soul_cannon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_sparrowhawk_net";
newscript->pItemUse = ItemUse_item_sparrowhawk_net;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_voodoo_charm";
newscript->pItemUse = ItemUse_item_voodoo_charm;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_vorenthals_presence";
newscript->pItemUse = ItemUse_item_vorenthals_presence;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_yehkinyas_bramble";
newscript->pItemUse = ItemUse_item_yehkinyas_bramble;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_zezzaks_shard";
newscript->pItemUse = ItemUse_item_zezzak_shard;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/item/item_test.cpp b/src/bindings/scripts/scripts/item/item_test.cpp
index a1e3b6c13c1..1dce7157e21 100644
--- a/src/bindings/scripts/scripts/item/item_test.cpp
+++ b/src/bindings/scripts/scripts/item/item_test.cpp
@@ -38,5 +38,5 @@ void AddSC_item_test()
newscript = new Script;
newscript->Name="item_test";
newscript->pItemUse = ItemUse_item_test;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp b/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp
index d0faf45c792..efc5e4b7b3a 100644
--- a/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp
+++ b/src/bindings/scripts/scripts/npc/npc_innkeeper.cpp
@@ -140,5 +140,5 @@ void AddSC_npc_innkeeper()
newscript->Name="npc_innkeeper";
newscript->pGossipHello = &GossipHello_npc_innkeeper;
newscript->pGossipSelect = &GossipSelect_npc_innkeeper;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/npc/npc_professions.cpp b/src/bindings/scripts/scripts/npc/npc_professions.cpp
index 30ecfc6788d..5061f195910 100644
--- a/src/bindings/scripts/scripts/npc/npc_professions.cpp
+++ b/src/bindings/scripts/scripts/npc/npc_professions.cpp
@@ -1177,29 +1177,29 @@ void AddSC_npc_professions()
newscript->Name="npc_prof_alchemy";
newscript->pGossipHello = &GossipHello_npc_prof_alchemy;
newscript->pGossipSelect = &GossipSelect_npc_prof_alchemy;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_prof_blacksmith";
newscript->pGossipHello = &GossipHello_npc_prof_blacksmith;
newscript->pGossipSelect = &GossipSelect_npc_prof_blacksmith;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_prof_leather";
newscript->pGossipHello = &GossipHello_npc_prof_leather;
newscript->pGossipSelect = &GossipSelect_npc_prof_leather;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_prof_tailor";
newscript->pGossipHello = &GossipHello_npc_prof_tailor;
newscript->pGossipSelect = &GossipSelect_npc_prof_tailor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
/*newscript = new Script;
newscript->Name="go_soothsaying_for_dummies";
newscript->pGOHello = &GOHello_go_soothsaying_for_dummies;
//newscript->pGossipSelect = &GossipSelect_go_soothsaying_for_dummies;
- m_scripts[nrscripts++] = newscript;*/
+ newscript->RegisterSelf();*/
}
diff --git a/src/bindings/scripts/scripts/npc/npcs_special.cpp b/src/bindings/scripts/scripts/npc/npcs_special.cpp
index 3e1cb0a9165..00116746a68 100644
--- a/src/bindings/scripts/scripts/npc/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/npc/npcs_special.cpp
@@ -835,44 +835,44 @@ void AddSC_npcs_special()
newscript->pReceiveEmote = &ReceiveEmote_npc_chicken_cluck;
newscript->pQuestAccept = &QuestAccept_npc_chicken_cluck;
newscript->pQuestComplete = &QuestComplete_npc_chicken_cluck;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_dancing_flames";
newscript->pReceiveEmote = &ReceiveEmote_npc_dancing_flames;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_injured_patient";
newscript->GetAI = GetAI_npc_injured_patient;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_doctor";
newscript->GetAI = GetAI_npc_doctor;
newscript->pQuestAccept = &QuestAccept_npc_doctor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_guardian";
newscript->GetAI = GetAI_npc_guardian;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_mount_vendor";
newscript->pGossipHello = &GossipHello_npc_mount_vendor;
newscript->pGossipSelect = &GossipSelect_npc_mount_vendor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_rogue_trainer";
newscript->pGossipHello = &GossipHello_npc_rogue_trainer;
newscript->pGossipSelect = &GossipSelect_npc_rogue_trainer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_sayge";
newscript->pGossipHello = &GossipHello_npc_sayge;
newscript->pGossipSelect = &GossipSelect_npc_sayge;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp b/src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp
index 98597afae3a..bb43a989a6b 100644
--- a/src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp
+++ b/src/bindings/scripts/scripts/zone/alterac_mountains/alterac_mountains.cpp
@@ -58,5 +58,5 @@ void AddSC_alterac_mountains()
newscript = new Script;
newscript->Name="npc_ravenholdt";
newscript->GetAI = GetAI_npc_ravenholdt;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp
index 055e0cbdbb9..810486aede7 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp
@@ -348,15 +348,15 @@ void AddSC_boss_exarch_maladaar()
newscript = new Script;
newscript->Name="boss_exarch_maladaar";
newscript->GetAI = GetAI_boss_exarch_maladaar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_avatar_of_martyred";
newscript->GetAI = GetAI_mob_avatar_of_martyred;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_stolen_soul";
newscript->GetAI = GetAI_mob_stolen_soul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp
index 3db39e4f477..a9589736784 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp
@@ -271,10 +271,10 @@ void AddSC_boss_nexusprince_shaffar()
newscript = new Script;
newscript->Name="boss_nexusprince_shaffar";
newscript->GetAI = GetAI_boss_nexusprince_shaffar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_ethereal_beacon";
newscript->GetAI = GetAI_mob_ethereal_beacon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp
index d4c950c754b..3542c3e484a 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp
@@ -134,5 +134,5 @@ void AddSC_boss_pandemonius()
newscript = new Script;
newscript->Name="boss_pandemonius";
newscript->GetAI = GetAI_boss_pandemonius;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp
index 1b77d81a908..0581e9ac3af 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp
@@ -392,25 +392,25 @@ void AddSC_boss_darkweaver_syth()
newscript = new Script;
newscript->Name="boss_darkweaver_syth";
newscript->GetAI = GetAI_boss_darkweaver_syth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_syth_fire";
newscript->GetAI = GetAI_mob_syth_arcane;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_syth_arcane";
newscript->GetAI = GetAI_mob_syth_arcane;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_syth_frost";
newscript->GetAI = GetAI_mob_syth_frost;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_syth_shadow";
newscript->GetAI = GetAI_mob_syth_shadow;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp
index ab9cd0f083b..be69ee79844 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp
@@ -219,5 +219,5 @@ void AddSC_boss_talon_king_ikiss()
newscript = new Script;
newscript->Name="boss_talon_king_ikiss";
newscript->GetAI = GetAI_boss_talon_king_ikiss;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp
index b49d18445c2..4ae6ad5c7a4 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp
@@ -70,5 +70,5 @@ void AddSC_instance_sethekk_halls()
newscript = new Script;
newscript->Name = "instance_sethekk_halls";
newscript->GetInstanceData = GetInstanceData_instance_sethekk_halls;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp
index e565becfaba..20bf7c2d95e 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp
@@ -194,5 +194,5 @@ void AddSC_boss_ambassador_hellmaw()
newscript = new Script;
newscript->Name="boss_ambassador_hellmaw";
newscript->GetAI = GetAI_boss_ambassador_hellmaw;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp
index ed2784471b3..8dd0a5f7060 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp
@@ -173,5 +173,5 @@ void AddSC_boss_blackheart_the_inciter()
newscript = new Script;
newscript->Name="boss_blackheart_the_inciter";
newscript->GetAI = GetAI_boss_blackheart_the_inciter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
index 79553b85ff2..ed7108ad3e7 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
@@ -363,10 +363,10 @@ void AddSC_boss_grandmaster_vorpil()
newscript = new Script;
newscript->Name="boss_grandmaster_vorpil";
newscript->GetAI = GetAI_boss_grandmaster_vorpil;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_voidtraveler";
newscript->GetAI = GetAI_mob_voidtraveler;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp
index 5b223b8d5ad..a5c387dc317 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp
@@ -148,5 +148,5 @@ void AddSC_boss_murmur()
newscript = new Script;
newscript->Name="boss_murmur";
newscript->GetAI = GetAI_boss_murmur;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp
index 1d482754cbc..ff5afc179e2 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp
@@ -174,5 +174,5 @@ void AddSC_instance_shadow_labyrinth()
newscript = new Script;
newscript->Name = "instance_shadow_labyrinth";
newscript->GetInstanceData = GetInstanceData_instance_shadow_labyrinth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/azshara/azshara.cpp b/src/bindings/scripts/scripts/zone/azshara/azshara.cpp
index 92c522fba60..5a62f5ee6c5 100644
--- a/src/bindings/scripts/scripts/zone/azshara/azshara.cpp
+++ b/src/bindings/scripts/scripts/zone/azshara/azshara.cpp
@@ -492,23 +492,23 @@ void AddSC_azshara()
newscript = new Script;
newscript->Name="mobs_spitelashes";
newscript->GetAI = GetAI_mobs_spitelashes;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_loramus_thalipedes";
newscript->pGossipHello = &GossipHello_npc_loramus_thalipedes;
newscript->pGossipSelect = &GossipSelect_npc_loramus_thalipedes;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_rizzle_sprysprocket";
newscript->GetAI = GetAI_mob_rizzle_sprysprocket;
newscript->pGossipHello = &GossipHello_mob_rizzle_sprysprocket;
newscript->pGossipSelect = &GossipSelect_mob_rizzle_sprysprocket;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_depth_charge";
newscript->GetAI = GetAI_mob_depth_charge;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp b/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp
index 2908dc04285..f688892d709 100644
--- a/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp
+++ b/src/bindings/scripts/scripts/zone/azshara/boss_azuregos.cpp
@@ -149,5 +149,5 @@ void AddSC_boss_azuregos()
newscript = new Script;
newscript->Name="boss_azuregos";
newscript->GetAI = GetAI_boss_azuregos;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
index 43209b64ba8..03e26504228 100644
--- a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
+++ b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
@@ -350,23 +350,23 @@ void AddSC_azuremyst_isle()
newscript = new Script;
newscript->Name="npc_draenei_survivor";
newscript->GetAI = GetAI_npc_draenei_survivor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_engineer_spark_overgrind";
newscript->GetAI = GetAI_npc_engineer_spark_overgrind;
newscript->pGossipHello = &GossipHello_npc_engineer_spark_overgrind;
newscript->pGossipSelect = &GossipSelect_npc_engineer_spark_overgrind;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_injured_draenei";
newscript->GetAI = GetAI_npc_injured_draenei;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_susurrus";
newscript->pGossipHello = &GossipHello_npc_susurrus;
newscript->pGossipSelect = &GossipSelect_npc_susurrus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp
index 788f4e2b8ce..468efc4d6a3 100644
--- a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp
+++ b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp
@@ -369,22 +369,22 @@ void AddSC_the_barrens()
newscript->Name="npc_beaten_corpse";
newscript->pGossipHello = &GossipHello_npc_beaten_corpse;
newscript->pGossipSelect = &GossipSelect_npc_beaten_corpse;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_sputtervalve";
newscript->pGossipHello = &GossipHello_npc_sputtervalve;
newscript->pGossipSelect = &GossipSelect_npc_sputtervalve;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_taskmaster_fizzule";
newscript->GetAI = GetAI_npc_taskmaster_fizzule;
newscript->pReceiveEmote = &ReciveEmote_npc_taskmaster_fizzule;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_twiggy_flathead";
newscript->GetAI = GetAI_npc_twiggy_flathead;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp
index 757f6acef06..68b581bae1c 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/black_temple.cpp
@@ -64,5 +64,5 @@ void AddSC_black_temple()
newscript->Name = "npc_spirit_of_olum";
newscript->pGossipHello = GossipHello_npc_spirit_of_olum;
newscript->pGossipSelect = GossipSelect_npc_spirit_of_olum;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
index 44bf36cad93..3f56e3cd59b 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
@@ -361,5 +361,5 @@ void AddSC_boss_gurtogg_bloodboil()
newscript = new Script;
newscript->Name="boss_gurtogg_bloodboil";
newscript->GetAI = GetAI_boss_gurtogg_bloodboil;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
index ce03d8eac3a..c7f2ec460d9 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
@@ -2247,52 +2247,52 @@ void AddSC_boss_illidan()
newscript = new Script;
newscript->Name = "boss_illidan_stormrage";
newscript->GetAI = GetAI_boss_illidan_stormrage;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_akama_illidan";
newscript->GetAI = GetAI_npc_akama_at_illidan;
newscript->pGossipHello = GossipHello_npc_akama_at_illidan;
newscript->pGossipSelect = GossipSelect_npc_akama_at_illidan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_maiev_shadowsong";
newscript->GetAI = GetAI_boss_maiev;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_flame_of_azzinoth";
newscript->GetAI = GetAI_mob_flame_of_azzinoth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_blade_of_azzinoth";
newscript->GetAI = GetAI_blade_of_azzinoth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "gameobject_cage_trap";
newscript->pGOHello = GOHello_cage_trap;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_cage_trap_trigger";
newscript->GetAI = &GetAI_cage_trap_trigger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_shadow_demon";
newscript->GetAI = GetAI_shadow_demon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_demon_fire";
newscript->GetAI = GetAI_demonfire;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_parasitic_shadowfiend";
newscript->GetAI = GetAI_parasitic_shadowfiend;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp
index 0f5d2af3c22..ee8a2c8348e 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp
@@ -357,5 +357,5 @@ void AddSC_boss_mother_shahraz()
newscript = new Script;
newscript->Name="boss_mother_shahraz";
newscript->GetAI = GetAI_boss_shahraz;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
index 3d6233ca3f7..8c5bdbc4a4a 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
@@ -723,25 +723,25 @@ void AddSC_boss_reliquary_of_souls()
newscript = new Script;
newscript->Name="boss_reliquary_of_souls";
newscript->GetAI = GetAI_boss_reliquary_of_souls;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_essence_of_suffering";
newscript->GetAI = GetAI_boss_essence_of_suffering;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_essence_of_desire";
newscript->GetAI = GetAI_boss_essence_of_desire;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_essence_of_anger";
newscript->GetAI = GetAI_boss_essence_of_anger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_enslaved_soul";
newscript->GetAI = GetAI_npc_enslaved_soul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
index 9c1d50950dc..3cd73df1bc7 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
@@ -796,22 +796,22 @@ void AddSC_boss_shade_of_akama()
newscript = new Script;
newscript->Name="boss_shade_of_akama";
newscript->GetAI = GetAI_boss_shade_of_akama;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_ashtongue_channeler";
newscript->GetAI = GetAI_mob_ashtongue_channeler;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_ashtongue_sorcerer";
newscript->GetAI = GetAI_mob_ashtongue_sorcerer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_akama_shade";
newscript->GetAI = GetAI_npc_akama_shade;
newscript->pGossipHello = &GossipHello_npc_akama;
newscript->pGossipSelect = &GossipSelect_npc_akama;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp
index d6b2e08fac0..640977d0eb9 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp
@@ -236,10 +236,10 @@ void AddSC_boss_supremus()
newscript = new Script;
newscript->Name="boss_supremus";
newscript->GetAI = GetAI_boss_supremus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="molten_flame";
newscript->GetAI = GetAI_molten_flame;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp
index e2ab402c7ff..97fcde9265f 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp
@@ -575,15 +575,15 @@ void AddSC_boss_teron_gorefiend()
newscript = new Script;
newscript->Name = "mob_doom_blossom";
newscript->GetAI = GetAI_mob_doom_blossom;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_shadowy_construct";
newscript->GetAI = GetAI_mob_shadowy_construct;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_teron_gorefiend";
newscript->GetAI = GetAI_boss_teron_gorefiend;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
index f49c2ef17c7..f2fe6f64f2f 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
@@ -258,10 +258,10 @@ void AddSC_boss_najentus()
newscript = new Script;
newscript->Name="boss_najentus";
newscript->GetAI = GetAI_boss_najentus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "go_najentus_spine";
newscript->pGOHello = &GOHello_go_najentus_spine;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp b/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp
index 6e5cabc034c..42197029a89 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/illidari_council.cpp
@@ -855,30 +855,30 @@ void AddSC_boss_illidari_council()
newscript = new Script;
newscript->Name="mob_illidari_council";
newscript->GetAI = GetAI_mob_illidari_council;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_blood_elf_council_voice_trigger";
newscript->GetAI = GetAI_mob_blood_elf_council_voice_trigger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_gathios_the_shatterer";
newscript->GetAI = GetAI_boss_gathios_the_shatterer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lady_malande";
newscript->GetAI = GetAI_boss_lady_malande;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_veras_darkshadow";
newscript->GetAI = GetAI_boss_veras_darkshadow;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_high_nethermancer_zerevor";
newscript->GetAI = GetAI_boss_high_nethermancer_zerevor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp
index cfeb700282b..0ff92762389 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp
@@ -332,5 +332,5 @@ void AddSC_instance_black_temple()
newscript = new Script;
newscript->Name = "instance_black_temple";
newscript->GetInstanceData = GetInstanceData_instance_black_temple;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp
index 95a920d39a3..c6e1cbcafe9 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/blackrock_depths.cpp
@@ -221,17 +221,17 @@ void AddSC_blackrock_depths()
newscript = new Script;
newscript->Name="phalanx";
newscript->GetAI = GetAI_mob_phalanx;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_kharan_mighthammer";
newscript->pGossipHello = &GossipHello_npc_kharan_mighthammer;
newscript->pGossipSelect = &GossipSelect_npc_kharan_mighthammer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_lokhtos_darkbargainer";
newscript->pGossipHello = &GossipHello_npc_lokhtos_darkbargainer;
newscript->pGossipSelect = &GossipSelect_npc_lokhtos_darkbargainer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp
index b63691a3b6e..2bb2a2ae004 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp
@@ -102,5 +102,5 @@ void AddSC_boss_ambassador_flamelash()
newscript = new Script;
newscript->Name="boss_ambassador_flamelash";
newscript->GetAI = GetAI_boss_ambassador_flamelash;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_angerrel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_angerrel.cpp
index 13b9f31e734..cbf895cc3e4 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_angerrel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_angerrel.cpp
@@ -87,5 +87,5 @@ void AddSC_boss_angerrel()
newscript = new Script;
newscript->Name="boss_angerrel";
newscript->GetAI = GetAI_boss_angerrel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp
index 50cf2af8169..091863de655 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_anubshiah.cpp
@@ -111,5 +111,5 @@ void AddSC_boss_anubshiah()
newscript = new Script;
newscript->Name="boss_anubshiah";
newscript->GetAI = GetAI_boss_anubshiah;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doomrel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doomrel.cpp
index b58ebc7b97a..867afe417cd 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doomrel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doomrel.cpp
@@ -135,5 +135,5 @@ void AddSC_boss_doomrel()
newscript = new Script;
newscript->Name="boss_doomrel";
newscript->GetAI = GetAI_boss_doomrel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doperel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doperel.cpp
index f9da16dd2fd..3c394476106 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doperel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_doperel.cpp
@@ -87,5 +87,5 @@ void AddSC_boss_doperel()
newscript = new Script;
newscript->Name="boss_doperel";
newscript->GetAI = GetAI_boss_doperel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp
index e8b1fb791ee..d463ed7f38f 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp
@@ -100,5 +100,5 @@ void AddSC_boss_draganthaurissan()
newscript = new Script;
newscript->Name="boss_emperor_dagran_thaurissan";
newscript->GetAI = GetAI_boss_draganthaurissan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_general_angerforge.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_general_angerforge.cpp
index 0760bc65733..7e3b8d9fba7 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_general_angerforge.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_general_angerforge.cpp
@@ -163,5 +163,5 @@ void AddSC_boss_general_angerforge()
newscript = new Script;
newscript->Name="boss_general_angerforge";
newscript->GetAI = GetAI_boss_general_angerforge;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gloomrel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gloomrel.cpp
index 30caa104b31..966fe4b8c22 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gloomrel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gloomrel.cpp
@@ -138,5 +138,5 @@ void AddSC_boss_gloomrel()
newscript->GetAI = GetAI_boss_gloomrel;
newscript->pGossipHello = &GossipHello_boss_gloomrel;
newscript->pGossipSelect = &GossipSelect_boss_gloomrel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp
index 91770069779..f2b617b73f0 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp
@@ -77,5 +77,5 @@ void AddSC_boss_gorosh_the_dervish()
newscript = new Script;
newscript->Name="boss_gorosh_the_dervish";
newscript->GetAI = GetAI_boss_gorosh_the_dervish;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp
index 7e489cca5a7..5005bb3935a 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_grizzle.cpp
@@ -82,5 +82,5 @@ void AddSC_boss_grizzle()
newscript = new Script;
newscript->Name="boss_grizzle";
newscript->GetAI = GetAI_boss_grizzle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_haterel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_haterel.cpp
index 778c68f73d3..53a94865002 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_haterel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_haterel.cpp
@@ -101,5 +101,5 @@ void AddSC_boss_haterel()
newscript = new Script;
newscript->Name="boss_haterel";
newscript->GetAI = GetAI_boss_haterel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp
index 8ee1a00c85b..43aa38ba4d4 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp
@@ -101,5 +101,5 @@ void AddSC_boss_high_interrogator_gerstahn()
newscript = new Script;
newscript->Name="boss_high_interrogator_gerstahn";
newscript->GetAI = GetAI_boss_high_interrogator_gerstahn;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp
index 0d163d31775..7703d6b2b31 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_magmus.cpp
@@ -80,5 +80,5 @@ void AddSC_boss_magmus()
newscript = new Script;
newscript->Name="boss_magmus";
newscript->GetAI = GetAI_boss_magmus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp
index 208353e66f3..68923722380 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp
@@ -95,5 +95,5 @@ void AddSC_boss_moira_bronzebeard()
newscript = new Script;
newscript->Name="boss_moira_bronzebeard";
newscript->GetAI = GetAI_boss_moira_bronzebeard;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_seethrel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_seethrel.cpp
index 93f3c124f29..e8753971898 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_seethrel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_seethrel.cpp
@@ -111,5 +111,5 @@ void AddSC_boss_seethrel()
newscript = new Script;
newscript->Name="boss_seethrel";
newscript->GetAI = GetAI_boss_seethrel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_vilerel.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_vilerel.cpp
index 0ecf70148fe..db1b0923f4c 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_depths/boss_vilerel.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_depths/boss_vilerel.cpp
@@ -97,5 +97,5 @@ void AddSC_boss_vilerel()
newscript = new Script;
newscript->Name="boss_vilerel";
newscript->GetAI = GetAI_boss_vilerel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp
index c26ba2ed6b9..56f4b3f385f 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_drakkisath.cpp
@@ -97,5 +97,5 @@ void AddSC_boss_drakkisath()
newscript = new Script;
newscript->Name="boss_drakkisath";
newscript->GetAI = GetAI_boss_drakkisath;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp
index 68107e820bf..d6089c269e7 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_gyth.cpp
@@ -201,5 +201,5 @@ void AddSC_boss_gyth()
newscript = new Script;
newscript->Name="boss_gyth";
newscript->GetAI = GetAI_boss_gyth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp
index 0b2c09acccf..e0c5d69d631 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_halycon.cpp
@@ -91,5 +91,5 @@ void AddSC_boss_halycon()
newscript = new Script;
newscript->Name="boss_halycon";
newscript->GetAI = GetAI_boss_halycon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_highlord_omokk.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_highlord_omokk.cpp
index afaedcc4ad8..0ee0a9df7f8 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_highlord_omokk.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_highlord_omokk.cpp
@@ -127,5 +127,5 @@ void AddSC_boss_highlordomokk()
newscript = new Script;
newscript->Name="boss_highlord_omokk";
newscript->GetAI = GetAI_boss_highlordomokk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp
index 8c1d3096597..c9686346057 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp
@@ -82,5 +82,5 @@ void AddSC_boss_mothersmolderweb()
newscript = new Script;
newscript->Name="boss_mother_smolderweb";
newscript->GetAI = GetAI_boss_mothersmolderweb;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp
index 5ab5847e38a..5852a12302e 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp
@@ -123,5 +123,5 @@ void AddSC_boss_overlordwyrmthalak()
newscript = new Script;
newscript->Name="boss_overlord_wyrmthalak";
newscript->GetAI = GetAI_boss_overlordwyrmthalak;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp
index f7705c647af..cbabb24d752 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp
@@ -89,5 +89,5 @@ void AddSC_boss_pyroguard_emberseer()
newscript = new Script;
newscript->Name="boss_pyroguard_emberseer";
newscript->GetAI = GetAI_boss_pyroguard_emberseer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp
index 7c0901e1f40..82561cb954f 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp
@@ -81,5 +81,5 @@ void AddSC_boss_quatermasterzigris()
newscript = new Script;
newscript->Name="quartermaster_zigris";
newscript->GetAI = GetAI_boss_quatermasterzigris;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_rend_blackhand.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_rend_blackhand.cpp
index 7ca84b3c429..b80a941ad17 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_rend_blackhand.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_rend_blackhand.cpp
@@ -87,5 +87,5 @@ void AddSC_boss_rend_blackhand()
newscript = new Script;
newscript->Name="boss_rend_blackhand";
newscript->GetAI = GetAI_boss_rend_blackhand;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp
index 17c73e43c82..83a324a2c38 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp
@@ -91,5 +91,5 @@ void AddSC_boss_shadowvosh()
newscript = new Script;
newscript->Name="boss_shadow_hunter_voshgajin";
newscript->GetAI = GetAI_boss_shadowvosh;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_the_beast.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_the_beast.cpp
index d7e403d0e72..586addd9d76 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_the_beast.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_the_beast.cpp
@@ -89,5 +89,5 @@ void AddSC_boss_thebeast()
newscript = new Script;
newscript->Name="boss_the_beast";
newscript->GetAI = GetAI_boss_thebeast;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_warmaster_voone.cpp b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_warmaster_voone.cpp
index 7377b46526f..bcc1469ccd9 100644
--- a/src/bindings/scripts/scripts/zone/blackrock_spire/boss_warmaster_voone.cpp
+++ b/src/bindings/scripts/scripts/zone/blackrock_spire/boss_warmaster_voone.cpp
@@ -117,5 +117,5 @@ void AddSC_boss_warmastervoone()
newscript = new Script;
newscript->Name="boss_warmaster_voone";
newscript->GetAI = GetAI_boss_warmastervoone;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp
index 0e40276903a..2c69e8ff599 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp
@@ -124,5 +124,5 @@ void AddSC_boss_broodlord()
newscript = new Script;
newscript->Name="boss_broodlord";
newscript->GetAI = GetAI_boss_broodlord;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp
index ea683bd1a13..920a50d4e49 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_chromaggus.cpp
@@ -310,5 +310,5 @@ void AddSC_boss_chromaggus()
newscript = new Script;
newscript->Name="boss_chromaggus";
newscript->GetAI = GetAI_boss_chromaggus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp
index 703dec09536..0dd8095a94b 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_ebonroc.cpp
@@ -99,5 +99,5 @@ void AddSC_boss_ebonroc()
newscript = new Script;
newscript->Name="boss_ebonroc";
newscript->GetAI = GetAI_boss_ebonroc;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
index 05a3e36948b..c1915d45a15 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
@@ -90,5 +90,5 @@ void AddSC_boss_firemaw()
newscript = new Script;
newscript->Name="boss_firemaw";
newscript->GetAI = GetAI_boss_firemaw;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
index fa34406b1fe..fbc8f4fa51a 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
@@ -90,5 +90,5 @@ void AddSC_boss_flamegor()
newscript = new Script;
newscript->Name="boss_flamegor";
newscript->GetAI = GetAI_boss_flamegor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp
index b819fde0bd5..741e61ba4de 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_nefarian.cpp
@@ -223,5 +223,5 @@ void AddSC_boss_nefarian()
newscript = new Script;
newscript->Name="boss_nefarian";
newscript->GetAI = GetAI_boss_nefarian;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
index bf76a08897f..98615b47758 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
@@ -127,5 +127,5 @@ void AddSC_boss_razorgore()
newscript = new Script;
newscript->Name="boss_razorgore";
newscript->GetAI = GetAI_boss_razorgore;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp
index 05e4b39af7d..a708a7de195 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_vaelastrasz.cpp
@@ -257,5 +257,5 @@ void AddSC_boss_vael()
newscript->GetAI = GetAI_boss_vael;
newscript->pGossipHello = &GossipHello_boss_vael;
newscript->pGossipSelect = &GossipSelect_boss_vael;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_victor_nefarius.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_victor_nefarius.cpp
index c9e92c7b75f..70bb6c15113 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_victor_nefarius.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_victor_nefarius.cpp
@@ -390,5 +390,5 @@ void AddSC_boss_victor_nefarius()
newscript->GetAI = GetAI_boss_victor_nefarius;
newscript->pGossipHello = &GossipHello_boss_victor_nefarius;
newscript->pGossipSelect = &GossipSelect_boss_victor_nefarius;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp b/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp
index 99dc4dbc82c..c47153aed7a 100644
--- a/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp
+++ b/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp
@@ -406,33 +406,33 @@ void AddSC_blades_edge_mountains()
newscript = new Script;
newscript->Name="mobs_bladespire_ogre";
newscript->GetAI = GetAI_mobs_bladespire_ogre;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mobs_nether_drake";
newscript->GetAI = GetAI_mobs_nether_drake;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_daranelle";
newscript->GetAI = GetAI_npc_daranelle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_overseer_nuaar";
newscript->pGossipHello = &GossipHello_npc_overseer_nuaar;
newscript->pGossipSelect = &GossipSelect_npc_overseer_nuaar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_saikkal_the_elder";
newscript->pGossipHello = &GossipHello_npc_saikkal_the_elder;
newscript->pGossipSelect = &GossipSelect_npc_saikkal_the_elder;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_skyguard_handler_irena";
newscript->pGossipHello = &GossipHello_npc_skyguard_handler_irena;
newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_irena;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp b/src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp
index 9212f13946a..b47abcb4c15 100644
--- a/src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp
+++ b/src/bindings/scripts/scripts/zone/blasted_lands/blasted_lands.cpp
@@ -149,11 +149,11 @@ void AddSC_blasted_lands()
newscript->Name="npc_deathly_usher";
newscript->pGossipHello = &GossipHello_npc_deathly_usher;
newscript->pGossipSelect = &GossipSelect_npc_deathly_usher;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_fallen_hero_of_horde";
newscript->pGossipHello = &GossipHello_npc_fallen_hero_of_horde;
newscript->pGossipSelect = &GossipSelect_npc_fallen_hero_of_horde;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp b/src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp
index 9de7b6d6085..250c382f028 100644
--- a/src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp
+++ b/src/bindings/scripts/scripts/zone/blasted_lands/boss_kruul.cpp
@@ -178,5 +178,5 @@ void AddSC_boss_kruul()
newscript = new Script;
newscript->Name="boss_kruul";
newscript->GetAI = GetAI_boss_kruul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp b/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
index e52386fc020..3705d195ca3 100644
--- a/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
+++ b/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
@@ -131,11 +131,11 @@ void AddSC_bloodmyst_isle()
newscript = new Script;
newscript->Name="mob_webbed_creature";
newscript->GetAI = GetAI_mob_webbed_creature;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_captured_sunhawk_agent";
newscript->pGossipHello = &GossipHello_npc_captured_sunhawk_agent;
newscript->pGossipSelect = &GossipSelect_npc_captured_sunhawk_agent;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp b/src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp
index bd926a2e7cc..7f0c2f45118 100644
--- a/src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp
+++ b/src/bindings/scripts/scripts/zone/burning_steppes/burning_steppes.cpp
@@ -147,5 +147,5 @@ void AddSC_burning_steppes()
newscript->GetAI = GetAI_npc_ragged_john;
newscript->pGossipHello = &GossipHello_npc_ragged_john;
newscript->pGossipSelect = &GossipSelect_npc_ragged_john;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp
index f6dd7a167ff..db167ff5ab9 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp
@@ -117,5 +117,5 @@ void AddSC_boss_aeonus()
newscript = new Script;
newscript->Name="boss_aeonus";
newscript->GetAI = GetAI_boss_aeonus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp
index b6d00be0889..fcaade46067 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp
@@ -105,5 +105,5 @@ void AddSC_boss_chrono_lord_deja()
newscript = new Script;
newscript->Name="boss_chrono_lord_deja";
newscript->GetAI = GetAI_boss_chrono_lord_deja;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp
index a59ecc8e4b6..2dad8913576 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp
@@ -139,5 +139,5 @@ void AddSC_boss_temporus()
newscript = new Script;
newscript->Name="boss_temporus";
newscript->GetAI = GetAI_boss_temporus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp
index 7e25c0c9b15..ab208aafba9 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp
@@ -769,20 +769,20 @@ void AddSC_boss_archimonde()
newscript = new Script;
newscript->Name="boss_archimonde";
newscript->GetAI = GetAI_boss_archimonde;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_doomfire";
newscript->GetAI = GetAI_mob_doomfire;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_doomfire_targetting";
newscript->GetAI = GetAI_mob_doomfire_targetting;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_ancient_wisp";
newscript->GetAI = GetAI_mob_ancient_wisp;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal.cpp
index 837f1f09872..51f147badc2 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal.cpp
@@ -200,18 +200,18 @@ void AddSC_hyjal()
newscript->GetAI = GetAI_npc_jaina_proudmoore;
newscript->pGossipHello = &GossipHello_npc_jaina_proudmoore;
newscript->pGossipSelect = &GossipSelect_npc_jaina_proudmoore;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_thrall";
newscript->GetAI = GetAI_npc_thrall;
newscript->pGossipHello = &GossipHello_npc_thrall;
newscript->pGossipSelect = &GossipSelect_npc_thrall;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_tyrande_whisperwind";
newscript->pGossipHello = &GossipHello_npc_tyrande_whisperwind;
newscript->pGossipSelect = &GossipSelect_npc_tyrande_whisperwind;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp
index a6f8e3a7305..3c3971d6036 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp
@@ -199,5 +199,5 @@ void AddSC_instance_mount_hyjal()
newscript = new Script;
newscript->Name = "instance_hyjal";
newscript->GetInstanceData = GetInstanceData_instance_mount_hyjal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp
index 19aff777b23..c43f5c2471c 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp
@@ -152,5 +152,5 @@ void AddSC_boss_captain_skarloc()
newscript = new Script;
newscript->Name="boss_captain_skarloc";
newscript->GetAI = GetAI_boss_captain_skarloc;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp
index 734ea93ffbe..510ef7a039f 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp
@@ -146,5 +146,5 @@ void AddSC_boss_epoch_hunter()
newscript = new Script;
newscript->Name="boss_epoch_hunter";
newscript->GetAI = GetAI_boss_epoch_hunter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp
index 6733e4b8d41..76d96775056 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp
@@ -194,10 +194,10 @@ void AddSC_boss_lieutenant_drake()
newscript = new Script;
newscript->Name="go_barrel_old_hillsbrad";
newscript->pGOHello = &GOHello_go_barrel_old_hillsbrad;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lieutenant_drake";
newscript->GetAI = GetAI_boss_lieutenant_drake;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp
index a6e4b377358..38a20c8adaf 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp
@@ -174,5 +174,5 @@ void AddSC_instance_old_hillsbrad()
newscript = new Script;
newscript->Name = "instance_old_hillsbrad";
newscript->GetInstanceData = GetInstanceData_instance_old_hillsbrad;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp
index 659636e1d35..596d327bc42 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp
@@ -893,24 +893,24 @@ void AddSC_old_hillsbrad()
newscript->Name="npc_brazen";
newscript->pGossipHello = &GossipHello_npc_brazen;
newscript->pGossipSelect = &GossipSelect_npc_brazen;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_erozion";
newscript->pGossipHello = &GossipHello_npc_erozion;
newscript->pGossipSelect = &GossipSelect_npc_erozion;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_thrall_old_hillsbrad";
newscript->pGossipHello = &GossipHello_npc_thrall_old_hillsbrad;
newscript->pGossipSelect = &GossipSelect_npc_thrall_old_hillsbrad;
newscript->GetAI = GetAI_npc_thrall_old_hillsbrad;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_taretha";
newscript->pGossipHello = &GossipHello_npc_taretha;
newscript->pGossipSelect = &GossipSelect_npc_taretha;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
index 9199bcadaf1..42a707ff930 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
@@ -744,20 +744,20 @@ void AddSC_boss_fathomlord_karathress()
newscript = new Script;
newscript->Name="boss_fathomlord_karathress";
newscript->GetAI = GetAI_boss_fathomlord_karathress;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_fathomguard_sharkkis";
newscript->GetAI = GetAI_boss_fathomguard_sharkkis;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_fathomguard_tidalvess";
newscript->GetAI = GetAI_boss_fathomguard_tidalvess;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_fathomguard_caribdis";
newscript->GetAI = GetAI_boss_fathomguard_caribdis;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp
index 13b8ebbf312..07adcf4b225 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp
@@ -382,5 +382,5 @@ void AddSC_boss_hydross_the_unstable()
newscript = new Script;
newscript->Name="boss_hydross_the_unstable";
newscript->GetAI = GetAI_boss_hydross_the_unstable;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
index 49f750acb6c..232a828150c 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
@@ -1029,42 +1029,42 @@ void AddSC_boss_lady_vashj()
newscript = new Script;
newscript->Name="boss_lady_vashj";
newscript->GetAI = GetAI_boss_lady_vashj;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_enchanted_elemental";
newscript->GetAI = GetAI_mob_enchanted_elemental;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_tainted_elemental";
newscript->GetAI = GetAI_mob_tainted_elemental;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_toxic_sporebat";
newscript->GetAI = GetAI_mob_toxic_sporebat;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_coilfang_elite";
newscript->GetAI = GetAI_mob_coilfang_elite;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_coilfang_strider";
newscript->GetAI = GetAI_mob_coilfang_strider;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_shield_generator_channel";
newscript->GetAI = GetAI_mob_shield_generator_channel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="item_tainted_core";
newscript->pItemUse = ItemUse_item_tainted_core;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
index 913eef3ec4e..70d4d6d2c56 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
@@ -804,20 +804,20 @@ void AddSC_boss_leotheras_the_blind()
newscript = new Script;
newscript->Name="boss_leotheras_the_blind";
newscript->GetAI = GetAI_boss_leotheras_the_blind;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_leotheras_the_blind_demonform";
newscript->GetAI = GetAI_boss_leotheras_the_blind_demonform;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_greyheart_spellbinder";
newscript->GetAI = GetAI_mob_greyheart_spellbinder;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_inner_demon";
newscript->GetAI = GetAI_mob_inner_demon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp
index 924b15397ed..509eadc2006 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp
@@ -167,16 +167,16 @@ void AddSC_boss_the_lurker_below()
newscript = new Script;
newscript->Name="boss_the_lurker_below";
newscript->GetAI = GetAI_boss_the_lurker_below;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_coilfang_guardian";
newscript->GetAI = GetAI_mob_coilfang_guardian;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_coilfang_ambusher";
newscript->GetAI = GetAI_mob_coilfang_ambusher;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp
index fa6a57a7fe4..900c3aad6d9 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp
@@ -350,10 +350,10 @@ void AddSC_boss_morogrim_tidewalker()
newscript = new Script;
newscript->Name="boss_morogrim_tidewalker";
newscript->GetAI = GetAI_boss_morogrim_tidewalker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_water_globule";
newscript->GetAI = GetAI_mob_water_globule;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
index de0f829c3d1..25b6a1a54d5 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
@@ -215,5 +215,5 @@ void AddSC_instance_serpentshrine_cavern()
newscript = new Script;
newscript->Name = "instance_serpent_shrine";
newscript->GetInstanceData = GetInstanceData_instance_serpentshrine_cavern;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp
index f51a28d61b3..cb09a94044f 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp
@@ -188,10 +188,10 @@ void AddSC_boss_hydromancer_thespia()
newscript = new Script;
newscript->Name="boss_hydromancer_thespia";
newscript->GetAI = GetAI_boss_thespiaAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_coilfang_waterelemental";
newscript->GetAI = GetAI_mob_coilfang_waterelementalAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp
index d769b44d9cf..6f839359d0a 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp
@@ -271,10 +271,10 @@ void AddSC_boss_mekgineer_steamrigger()
newscript = new Script;
newscript->Name="boss_mekgineer_steamrigger";
newscript->GetAI = GetAI_boss_mekgineer_steamrigger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_steamrigger_mechanic";
newscript->GetAI = GetAI_mob_steamrigger_mechanic;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp
index 85c6657bebb..a3b3c68ba82 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp
@@ -226,10 +226,10 @@ void AddSC_boss_warlord_kalithresh()
newscript = new Script;
newscript->Name="mob_naga_distiller";
newscript->GetAI = GetAI_mob_naga_distiller;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_warlord_kalithresh";
newscript->GetAI = GetAI_boss_warlord_kalithresh;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp
index 798d04d6cfb..dc082244846 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp
@@ -166,5 +166,5 @@ void AddSC_instance_steam_vault()
newscript = new Script;
newscript->Name = "instance_steam_vault";
newscript->GetInstanceData = GetInstanceData_instance_steam_vault;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp
index 13ac880295b..34c854ad8bf 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp
@@ -147,10 +147,10 @@ void AddSC_boss_hungarfen()
newscript = new Script;
newscript->Name="boss_hungarfen";
newscript->GetAI = GetAI_boss_hungarfen;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_underbog_mushroom";
newscript->GetAI = GetAI_mob_underbog_mushroom;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp b/src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp
index c5f7bf6fc07..ee8c531593b 100644
--- a/src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp
+++ b/src/bindings/scripts/scripts/zone/dun_morogh/dun_morogh.cpp
@@ -94,5 +94,5 @@ void AddSC_dun_morogh()
newscript = new Script;
newscript->Name="npc_narm_faulk";
newscript->GetAI = GetAI_npc_narm_faulk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp b/src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp
index 7a8c1329b36..16e5d3fc62e 100644
--- a/src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp
+++ b/src/bindings/scripts/scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp
@@ -204,28 +204,28 @@ void AddSC_dustwallow_marsh()
newscript = new Script;
newscript->Name="mobs_risen_husk_spirit";
newscript->GetAI = GetAI_mobs_risen_husk_spirit;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_restless_apparition";
newscript->pGossipHello = &GossipHello_npc_restless_apparition;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_deserter_agitator";
newscript->GetAI = GetAI_npc_deserter_agitator;
newscript->pGossipHello = &GossipHello_npc_deserter_agitator;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_lady_jaina_proudmoore";
newscript->pGossipHello = &GossipHello_npc_lady_jaina_proudmoore;
newscript->pGossipSelect = &GossipSelect_npc_lady_jaina_proudmoore;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_nat_pagle";
newscript->pGossipHello = &GossipHello_npc_nat_pagle;
newscript->pGossipSelect = &GossipSelect_npc_nat_pagle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp b/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
index e8d44931f11..125fdf44817 100644
--- a/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
+++ b/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
@@ -158,23 +158,23 @@ void AddSC_eastern_plaguelands()
newscript = new Script;
newscript->Name="mobs_ghoul_flayer";
newscript->GetAI = GetAI_mobs_ghoul_flayer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_augustus_the_touched";
newscript->pGossipHello = &GossipHello_npc_augustus_the_touched;
newscript->pGossipSelect = &GossipSelect_npc_augustus_the_touched;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_darrowshire_spirit";
newscript->GetAI = GetAI_npc_darrowshire_spirit;
newscript->pGossipHello = &GossipHello_npc_darrowshire_spirit;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_tirion_fordring";
newscript->pGossipHello = &GossipHello_npc_tirion_fordring;
newscript->pGossipSelect = &GossipSelect_npc_tirion_fordring;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp b/src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp
index d91b4533de2..b1061213649 100644
--- a/src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/elwynn_forest/elwynn_forest.cpp
@@ -94,5 +94,5 @@ void AddSC_elwynn_forest()
newscript = new Script;
newscript->Name="npc_henze_faulk";
newscript->GetAI = GetAI_npc_henze_faulk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
index 932dea11a60..4f9c2a775af 100644
--- a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
+++ b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
@@ -152,12 +152,12 @@ void AddSC_eversong_woods()
newscript = new Script;
newscript->Name="mobs_mana_tapped";
newscript->GetAI = GetAI_mobs_mana_tapped;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name= "npc_prospector_anvilward";
newscript->GetAI = GetAI_npc_prospector_anvilward;
newscript->pGossipHello = &GossipHello_npc_prospector_anvilward;
newscript->pGossipSelect = &GossipSelect_npc_prospector_anvilward;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/felwood/felwood.cpp b/src/bindings/scripts/scripts/zone/felwood/felwood.cpp
index 59dc03456a4..2cd6d05579e 100644
--- a/src/bindings/scripts/scripts/zone/felwood/felwood.cpp
+++ b/src/bindings/scripts/scripts/zone/felwood/felwood.cpp
@@ -85,5 +85,5 @@ void AddSC_felwood()
newscript->Name="npcs_riverbreeze_and_silversky";
newscript->pGossipHello = &GossipHello_npcs_riverbreeze_and_silversky;
newscript->pGossipSelect = &GossipSelect_npcs_riverbreeze_and_silversky;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/feralas/feralas.cpp b/src/bindings/scripts/scripts/zone/feralas/feralas.cpp
index ca8c5d0a02d..e0a89fe5905 100644
--- a/src/bindings/scripts/scripts/zone/feralas/feralas.cpp
+++ b/src/bindings/scripts/scripts/zone/feralas/feralas.cpp
@@ -76,10 +76,10 @@ void AddSC_feralas()
newscript->Name="npc_gregan_brewspewer";
newscript->pGossipHello = &GossipHello_npc_gregan_brewspewer;
newscript->pGossipSelect = &GossipSelect_npc_gregan_brewspewer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_screecher_spirit";
newscript->pGossipHello = &GossipHello_npc_screecher_spirit;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
index 35c7213d033..ade3931c75d 100644
--- a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
+++ b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
@@ -133,22 +133,22 @@ void AddSC_ghostlands()
newscript->Name="npc_blood_knight_dawnstar";
newscript->pGossipHello = &GossipHello_npc_blood_knight_dawnstar;
newscript->pGossipSelect = &GossipSelect_npc_blood_knight_dawnstar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_budd_nedreck";
newscript->pGossipHello = &GossipHello_npc_budd_nedreck;
newscript->pGossipSelect = &GossipSelect_npc_budd_nedreck;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_rathis_tomber";
newscript->pGossipHello = &GossipHello_npc_rathis_tomber;
newscript->pGossipSelect = &GossipSelect_npc_rathis_tomber;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "go_gilded_brazier";
newscript->pGOHello = &GOHello_gilded_brazier;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp
index bb2487b892e..1616d75e376 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_gruul.cpp
@@ -300,5 +300,5 @@ void AddSC_boss_gruul()
newscript = new Script;
newscript->Name="boss_gruul";
newscript->GetAI = GetAI_boss_gruul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp
index 3c77b1a0acf..b0e53373a2f 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp
@@ -817,25 +817,25 @@ void AddSC_boss_high_king_maulgar()
newscript = new Script;
newscript->Name="boss_high_king_maulgar";
newscript->GetAI = GetAI_boss_high_king_maulgar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_kiggler_the_crazed";
newscript->GetAI = GetAI_boss_kiggler_the_crazed;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_blindeye_the_seer";
newscript->GetAI = GetAI_boss_blindeye_the_seer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_olm_the_summoner";
newscript->GetAI = GetAI_boss_olm_the_summoner;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_krosh_firehand";
newscript->GetAI = GetAI_boss_krosh_firehand;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp
index 062800da3f6..3d058060722 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp
@@ -184,5 +184,5 @@ void AddSC_instance_gruuls_lair()
newscript = new Script;
newscript->Name = "instance_gruuls_lair";
newscript->GetInstanceData = GetInstanceData_instance_gruuls_lair;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp
index 2237a85077a..1431be7dd51 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp
@@ -123,10 +123,10 @@ void AddSC_boss_broggok()
newscript = new Script;
newscript->Name="boss_broggok";
newscript->GetAI = GetAI_boss_broggokAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_broggok_poisoncloud";
newscript->GetAI = GetAI_mob_broggok_poisoncloudAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp
index bc5799ffe7e..092dfcd17be 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp
@@ -225,10 +225,10 @@ void AddSC_boss_kelidan_the_breaker()
newscript = new Script;
newscript->Name="boss_kelidan_the_breaker";
newscript->GetAI = GetAI_boss_kelidan_the_breaker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_shadowmoon_channeler";
newscript->GetAI = GetAI_mob_shadowmoon_channeler;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp
index ec85747032d..0c30651c9d5 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp
@@ -127,5 +127,5 @@ void AddSC_boss_the_maker()
newscript = new Script;
newscript->Name="boss_the_maker";
newscript->GetAI = GetAI_boss_the_makerAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp
index 676fbddf48c..1d8b1ec2c22 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp
@@ -209,5 +209,5 @@ void AddSC_boss_omor_the_unscarred()
newscript = new Script;
newscript->Name="boss_omor_the_unscarred";
newscript->GetAI = GetAI_boss_omor_the_unscarredAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp
index 21e9362a762..0d9e200c6e7 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp
@@ -164,5 +164,5 @@ void AddSC_boss_watchkeeper_gargolmar()
newscript = new Script;
newscript->Name="boss_watchkeeper_gargolmar";
newscript->GetAI = GetAI_boss_watchkeeper_gargolmarAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp
index 4d7fe35891d..4d819b3537b 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp
@@ -545,21 +545,21 @@ void AddSC_boss_magtheridon()
newscript = new Script;
newscript->Name="boss_magtheridon";
newscript->GetAI = GetAI_boss_magtheridon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_hellfire_channeler";
newscript->GetAI = GetAI_mob_hellfire_channeler;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_manticron_cube";
newscript->pGOHello = &GOHello_go_Manticron_Cube;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_abyssal";
newscript->GetAI = GetAI_mob_abyssalAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
} \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp
index d8f598f451e..51f22a1ff54 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp
@@ -282,5 +282,5 @@ void AddSC_instance_magtheridons_lair()
newscript = new Script;
newscript->Name = "instance_magtheridons_lair";
newscript->GetInstanceData = GetInstanceData_instance_magtheridons_lair;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp
index 9d8335c527b..299f72a041b 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp
@@ -444,15 +444,15 @@ void AddSC_boss_grand_warlock_nethekurse()
newscript = new Script;
newscript->Name="boss_grand_warlock_nethekurse";
newscript->GetAI = GetAI_boss_grand_warlock_nethekurse;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_fel_orc_convert";
newscript->GetAI = GetAI_mob_fel_orc_convert;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_lesser_shadow_fissure";
newscript->GetAI = GetAI_mob_lesser_shadow_fissure;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp
index 092e82df0ed..2c128b3c047 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp
@@ -394,10 +394,10 @@ void AddSC_boss_warbringer_omrogg()
newscript = new Script;
newscript->Name="boss_warbringer_omrogg";
newscript->GetAI = GetAI_boss_warbringer_omrogg;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_omrogg_heads";
newscript->GetAI = GetAI_mob_omrogg_heads;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp
index 9dc78cb82cb..bee90392fe3 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp
@@ -110,5 +110,5 @@ void AddSC_instance_shattered_halls()
newscript = new Script;
newscript->Name = "instance_shattered_halls";
newscript->GetInstanceData = GetInstanceData_instance_shattered_halls;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp b/src/bindings/scripts/scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp
index 51b4017b707..9b1822226a7 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp
@@ -137,5 +137,5 @@ void AddSC_boss_doomlordkazzak()
newscript = new Script;
newscript->Name="boss_doomlord_kazzak";
newscript->GetAI = GetAI_boss_doomlordkazzak;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
index 1c3a4c71725..81d23457aab 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
@@ -171,17 +171,17 @@ void AddSC_hellfire_peninsula()
newscript->Name="npc_wing_commander_dabiree";
newscript->pGossipHello = &GossipHello_npc_wing_commander_dabiree;
newscript->pGossipSelect = &GossipSelect_npc_wing_commander_dabiree;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_gryphoneer_windbellow";
newscript->pGossipHello = &GossipHello_npc_gryphoneer_windbellow;
newscript->pGossipSelect = &GossipSelect_npc_gryphoneer_windbellow;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_wing_commander_brack";
newscript->pGossipHello = &GossipHello_npc_wing_commander_brack;
newscript->pGossipSelect = &GossipSelect_npc_wing_commander_brack;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp b/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp
index 7bb51ad499c..701f208f2a3 100644
--- a/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp
+++ b/src/bindings/scripts/scripts/zone/ironforge/ironforge.cpp
@@ -89,5 +89,5 @@ void AddSC_ironforge()
newscript->Name="npc_royal_historian_archesonus";
newscript->pGossipHello = &GossipHello_npc_royal_historian_archesonus;
newscript->pGossipSelect = &GossipSelect_npc_royal_historian_archesonus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp b/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp
index 9b2c1cda518..2690ecfa0ac 100644
--- a/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp
+++ b/src/bindings/scripts/scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp
@@ -140,16 +140,16 @@ void AddSC_isle_of_queldanas()
newscript->Name="npc_ayren_cloudbreaker";
newscript->pGossipHello = &GossipHello_npc_ayren_cloudbreaker;
newscript->pGossipSelect = &GossipSelect_npc_ayren_cloudbreaker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_converted_sentry";
newscript->GetAI = GetAI_npc_converted_sentry;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_unrestrained_dragonhawk";
newscript->pGossipHello = &GossipHello_npc_unrestrained_dragonhawk;
newscript->pGossipSelect = &GossipSelect_npc_unrestrained_dragonhawk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp
index b560caad0d1..3c83b618604 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp
@@ -196,5 +196,5 @@ void AddSC_boss_curator()
newscript = new Script;
newscript->Name="boss_curator";
newscript->GetAI = GetAI_boss_curator;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp
index e0bbadf5650..b4075e72b73 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp
@@ -179,5 +179,5 @@ void AddSC_boss_maiden_of_virtue()
newscript = new Script;
newscript->Name="boss_maiden_of_virtue";
newscript->GetAI = GetAI_boss_maiden_of_virtue;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp
index 1be1a2df16f..1331e59c2f2 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_midnight.cpp
@@ -362,10 +362,10 @@ void AddSC_boss_attumen()
newscript = new Script;
newscript->Name="boss_attumen";
newscript->GetAI = GetAI_boss_attumen;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_midnight";
newscript->GetAI = GetAI_boss_midnight;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp
index 06a47787fa0..ce8f26ff0e5 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp
@@ -835,35 +835,35 @@ void AddSC_boss_moroes()
newscript = new Script;
newscript->Name="boss_moroes";
newscript->GetAI = GetAI_boss_moroes;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_baroness_dorothea_millstipe";
newscript->GetAI = GetAI_baroness_dorothea_millstipe;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_baron_rafe_dreuger";
newscript->GetAI = GetAI_baron_rafe_dreuger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lady_catriona_von_indi";
newscript->GetAI = GetAI_lady_catriona_von_indi;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lady_keira_berrybuck";
newscript->GetAI = GetAI_lady_keira_berrybuck;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lord_robin_daris";
newscript->GetAI = GetAI_lord_robin_daris;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lord_crispin_ference";
newscript->GetAI = GetAI_lord_crispin_ference;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
index 6dfa4cb01b7..6d4e75afdb9 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
@@ -666,10 +666,10 @@ void AddSC_boss_malchezaar()
newscript = new Script;
newscript->Name="boss_malchezaar";
newscript->GetAI = GetAI_boss_malchezaar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="netherspite_infernal";
newscript->GetAI = GetAI_netherspite_infernal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_shade_of_aran.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_shade_of_aran.cpp
index 20cdb5b2d7d..71325d21f22 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_shade_of_aran.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_shade_of_aran.cpp
@@ -654,20 +654,20 @@ void AddSC_boss_shade_of_aran()
newscript = new Script;
newscript->Name="boss_shade_of_aran";
newscript->GetAI = GetAI_boss_aran;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_shadow_of_aran";
newscript->GetAI = GetAI_shadow_of_aran;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_aran_elemental";
newscript->GetAI = GetAI_water_elemental;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
//newscript = new Script;
//newscript->Name="mob_aran_blizzard";
//newscript->GetAI = GetAI_boss_aran;
- //m_scripts[nrscripts++] = newscript;
+ //newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp
index ddf6e9cb451..00a8cd46281 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_terestian_illhoof.cpp
@@ -436,20 +436,20 @@ void AddSC_boss_terestian_illhoof()
newscript = new Script;
newscript->Name="boss_terestian_illhoof";
newscript->GetAI = GetAI_boss_terestian_illhoof;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_karazhan_imp";
newscript->GetAI = GetAI_mob_karazhan_imp;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_kilrek";
newscript->GetAI = GetAI_mob_kilrek;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_demon_chain";
newscript->GetAI = GetAI_mob_demon_chain;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
index 91dab811d00..2509445f3d0 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
@@ -1414,58 +1414,58 @@ void AddSC_bosses_opera()
newscript = new Script;
newscript->GetAI = GetAI_boss_dorothee;
newscript->Name = "boss_dorothee";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_boss_strawman;
newscript->Name = "boss_strawman";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_boss_tinhead;
newscript->Name = "boss_tinhead";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_boss_roar;
newscript->Name = "boss_roar";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_boss_crone;
newscript->Name = "boss_crone";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_mob_tito;
newscript->Name = "mob_tito";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_mob_cyclone;
newscript->Name = "mob_cyclone";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
// Hood
newscript = new Script;
newscript->pGossipHello = GossipHello_npc_grandmother;
newscript->pGossipSelect = GossipSelect_npc_grandmother;
newscript->Name = "npc_grandmother";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_boss_bigbadwolf;
newscript->Name = "boss_bigbadwolf";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
// Romeo And Juliet
newscript = new Script;
newscript->GetAI = GetAI_boss_julianne;
newscript->Name = "boss_julianne";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->GetAI = GetAI_boss_romulo;
newscript->Name = "boss_romulo";
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp
index f683eea5336..29e07fe254f 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp
@@ -249,5 +249,5 @@ void AddSC_instance_karazhan()
newscript = new Script;
newscript->Name = "instance_karazhan";
newscript->GetInstanceData = GetInstanceData_instance_karazhan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp
index 704a142cec9..404014565e6 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/karazhan.cpp
@@ -290,13 +290,13 @@ struct TRINITY_DLL_DECL npc_barnesAI : public npc_escortAI
return;
RaidWiped = true;
- for(Map::PlayerList::const_iterator i = PlayerList.begin();i != PlayerList.end(); ++i)
- {
- if (i->getSource()->isAlive() && !i->getSource()->isGameMaster())
- {
- RaidWiped = false;
- break;
- }
+ for(Map::PlayerList::const_iterator i = PlayerList.begin();i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && !i->getSource()->isGameMaster())
+ {
+ RaidWiped = false;
+ break;
+ }
}
if(RaidWiped)
@@ -460,11 +460,11 @@ void AddSC_karazhan()
newscript->Name = "npc_barnes";
newscript->pGossipHello = GossipHello_npc_barnes;
newscript->pGossipSelect = GossipSelect_npc_barnes;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_berthold";
newscript->pGossipHello = GossipHello_npc_berthold;
newscript->pGossipSelect = GossipSelect_npc_berthold;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp b/src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp
index 966bf7c40a3..0e48a72535f 100644
--- a/src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp
+++ b/src/bindings/scripts/scripts/zone/loch_modan/loch_modan.cpp
@@ -87,5 +87,5 @@ void AddSC_loch_modan()
newscript->Name="npc_mountaineer_pebblebitty";
newscript->pGossipHello = &GossipHello_npc_mountaineer_pebblebitty;
newscript->pGossipSelect = &GossipSelect_npc_mountaineer_pebblebitty;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
index 6bfb0d6464d..f08ff848237 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
@@ -761,35 +761,35 @@ void AddSC_boss_felblood_kaelthas()
newscript = new Script;
newscript->Name = "boss_felblood_kaelthas";
newscript->GetAI = GetAI_boss_felblood_kaelthas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_arcane_sphere";
newscript->GetAI = GetAI_mob_arcane_sphere;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_felkael_phoenix";
newscript->GetAI = GetAI_mob_felkael_phoenix;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_felkael_phoenix_egg";
newscript->GetAI = GetAI_mob_felkael_phoenix_egg;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_felkael_flamestrike";
newscript->GetAI = GetAI_mob_felkael_flamestrike;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_kael_orb";
newscript->pGOHello = &GOHello_go_kael_orb;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="go_movie_orb";
newscript->pGOHello = &GOHello_go_movie_orb;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
index bd4a336eff4..afae183a4ec 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
@@ -1355,60 +1355,60 @@ void AddSC_boss_priestess_delrissa()
newscript = new Script;
newscript->Name="boss_priestess_delrissa";
newscript->GetAI = GetAI_boss_priestess_delrissa;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_kagani_nightstrike";
newscript->GetAI = GetAI_boss_kagani_nightstrike;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_ellris_duskhallow";
newscript->GetAI = GetAI_ellris_duskhallow;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_eramas_brightblaze";
newscript->GetAI = GetAI_eramas_brightblaze;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_yazzai";
newscript->GetAI = GetAI_yazzai;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_warlord_salaris";
newscript->GetAI = GetAI_warlord_salaris;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_garaxxas";
newscript->GetAI = GetAI_garaxxas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_apoko";
newscript->GetAI = GetAI_apoko;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_zelfan";
newscript->GetAI = GetAI_zelfan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
/*newscript = new Script;
newscript->Name="mob_high_explosive_sheep";
newscript->GetAI = GetAI_mob_high_explosive_sheep;
- m_scripts[nrscripts++] = newscript;*/
+ newscript->RegisterSelf();*/
/*newscript = new Script;
newscript->Name="mob_fizzle";
newscript->GetAI = GetAI_mob_fizzle;
- m_scripts[nrscripts++] = newscript;*/
+ newscript->RegisterSelf();*/
/*newscript = new Script;
newscript->Name="mob_sliver";
newscript->GetAI = GetAI_mob_sliver;
- m_scripts[nrscripts++] = newscript;*/
+ newscript->RegisterSelf();*/
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp
index 24526dac185..83174dd5a4c 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp
@@ -403,10 +403,10 @@ void AddSC_boss_selin_fireheart()
newscript = new Script;
newscript->Name="boss_selin_fireheart";
newscript->GetAI = GetAI_boss_selin_fireheart;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_fel_crystal";
newscript->GetAI = GetAI_mob_fel_crystal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp
index ff11b425bd2..4f073cb884d 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp
@@ -238,10 +238,10 @@ void AddSC_boss_vexallus()
newscript = new Script;
newscript->Name="boss_vexallus";
newscript->GetAI = GetAI_boss_vexallus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_pure_energy";
newscript->GetAI = GetAI_mob_pure_energy;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp
index 8afecdc32e9..70d12865158 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp
@@ -249,5 +249,5 @@ void AddSC_instance_magisters_terrace()
newscript = new Script;
newscript->Name = "instance_magisters_terrace";
newscript->GetInstanceData = GetInstanceData_instance_magisters_terrace;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/maraudon/boss_celebras_the_cursed.cpp b/src/bindings/scripts/scripts/zone/maraudon/boss_celebras_the_cursed.cpp
index 543686e2648..8830b7f3e4b 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_celebras_the_cursed.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_celebras_the_cursed.cpp
@@ -93,5 +93,5 @@ void AddSC_boss_celebras_the_cursed()
newscript = new Script;
newscript->Name="celebras_the_cursed";
newscript->GetAI = GetAI_celebras_the_cursed;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp b/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp
index 20b93fe64b3..ab68f68c6e3 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_landslide.cpp
@@ -90,5 +90,5 @@ void AddSC_boss_landslide()
newscript = new Script;
newscript->Name="boss_landslide";
newscript->GetAI = GetAI_boss_landslide;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp b/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp
index c5d5a51ffb9..0ffe9cd7f56 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_noxxion.cpp
@@ -145,5 +145,5 @@ void AddSC_boss_noxxion()
newscript = new Script;
newscript->Name="boss_noxxion";
newscript->GetAI = GetAI_boss_noxxion;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp b/src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp
index 1920109f3d8..01cfb86a372 100644
--- a/src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp
+++ b/src/bindings/scripts/scripts/zone/maraudon/boss_princess_theradras.cpp
@@ -104,5 +104,5 @@ void AddSC_boss_ptheradras()
newscript = new Script;
newscript->Name="boss_princess_theradras";
newscript->GetAI = GetAI_boss_ptheradras;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_baron_geddon.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_baron_geddon.cpp
index 163926881f6..75cf6cb0a45 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_baron_geddon.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_baron_geddon.cpp
@@ -101,5 +101,5 @@ void AddSC_boss_baron_geddon()
newscript = new Script;
newscript->Name="boss_baron_geddon";
newscript->GetAI = GetAI_boss_baron_geddon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp
index 70e98d648ee..830af78c430 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_garr.cpp
@@ -140,10 +140,10 @@ void AddSC_boss_garr()
newscript = new Script;
newscript->Name="boss_garr";
newscript->GetAI = GetAI_boss_garr;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_firesworn";
newscript->GetAI = GetAI_mob_firesworn;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp
index f15c66f26af..dc8bd9a5d9c 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_gehennas.cpp
@@ -87,5 +87,5 @@ void AddSC_boss_gehennas()
newscript = new Script;
newscript->Name="boss_gehennas";
newscript->GetAI = GetAI_boss_gehennas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp
index 6d17621ceb2..ebefd0185fc 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_golemagg.cpp
@@ -192,10 +192,10 @@ void AddSC_boss_golemagg()
newscript = new Script;
newscript->Name="boss_golemagg";
newscript->GetAI = GetAI_boss_golemagg;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_core_rager";
newscript->GetAI = GetAI_mob_core_rager;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp
index 6e8938bc542..f45657c8dae 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_lucifron.cpp
@@ -86,5 +86,5 @@ void AddSC_boss_lucifron()
newscript = new Script;
newscript->Name="boss_lucifron";
newscript->GetAI = GetAI_boss_lucifron;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp
index a892c83f175..d08f393fbee 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_magmadar.cpp
@@ -93,5 +93,5 @@ void AddSC_boss_magmadar()
newscript = new Script;
newscript->Name="boss_magmadar";
newscript->GetAI = GetAI_boss_magmadar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_majordomo_executus.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_majordomo_executus.cpp
index d61f08ee7e7..43be23046ea 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_majordomo_executus.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_majordomo_executus.cpp
@@ -129,5 +129,5 @@ void AddSC_boss_majordomo()
newscript = new Script;
newscript->Name="boss_majordomo";
newscript->GetAI = GetAI_boss_majordomo;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp
index 723fba0edf7..d357d9580e9 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_ragnaros.cpp
@@ -313,5 +313,5 @@ void AddSC_boss_ragnaros()
newscript = new Script;
newscript->Name="boss_ragnaros";
newscript->GetAI = GetAI_boss_ragnaros;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp
index c9d4f4f3eec..c78b9ac3c91 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_shazzrah.cpp
@@ -117,5 +117,5 @@ void AddSC_boss_shazzrah()
newscript = new Script;
newscript->Name="boss_shazzrah";
newscript->GetAI = GetAI_boss_shazzrah;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/boss_sulfuron_harbinger.cpp b/src/bindings/scripts/scripts/zone/molten_core/boss_sulfuron_harbinger.cpp
index 8a2a7764daa..0bc0e8e729e 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/boss_sulfuron_harbinger.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/boss_sulfuron_harbinger.cpp
@@ -206,10 +206,10 @@ void AddSC_boss_sulfuron()
newscript = new Script;
newscript->Name="boss_sulfuron";
newscript->GetAI = GetAI_boss_sulfuron;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_flamewaker_priest";
newscript->GetAI = GetAI_mob_flamewaker_priest;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/instance_molten_core.cpp b/src/bindings/scripts/scripts/zone/molten_core/instance_molten_core.cpp
index 42a2ec35678..efba77f41f0 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/instance_molten_core.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/instance_molten_core.cpp
@@ -253,5 +253,5 @@ void AddSC_instance_molten_core()
newscript = new Script;
newscript->Name="instance_molten_core";
newscript->GetInstanceData = &GetInstance_instance_molten_core;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp b/src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp
index e36f56c7817..9446fb54a12 100644
--- a/src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp
+++ b/src/bindings/scripts/scripts/zone/molten_core/molten_core.cpp
@@ -84,5 +84,5 @@ void AddSC_molten_core()
newscript = new Script;
newscript->Name="mob_ancient_core_hound";
newscript->GetAI = GetAI_mob_ancient_core_hound;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp b/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp
index 7ac2326327b..1b0afbaaf94 100644
--- a/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp
+++ b/src/bindings/scripts/scripts/zone/moonglade/moonglade.cpp
@@ -545,27 +545,27 @@ void AddSC_moonglade()
newscript->Name="npc_bunthen_plainswind";
newscript->pGossipHello = &GossipHello_npc_bunthen_plainswind;
newscript->pGossipSelect = &GossipSelect_npc_bunthen_plainswind;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_great_bear_spirit";
newscript->pGossipHello = &GossipHello_npc_great_bear_spirit;
newscript->pGossipSelect = &GossipSelect_npc_great_bear_spirit;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_silva_filnaveth";
newscript->pGossipHello = &GossipHello_npc_silva_filnaveth;
newscript->pGossipSelect = &GossipSelect_npc_silva_filnaveth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_clintar_dreamwalker";
newscript->pQuestAccept = &QuestAccept_npc_clintar_dreamwalker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_clintar_spirit";
newscript->GetAI = GetAI_npc_clintar_spirit;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp b/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp
index d2fb6643423..44de5eab777 100644
--- a/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp
+++ b/src/bindings/scripts/scripts/zone/mulgore/mulgore.cpp
@@ -60,5 +60,5 @@ void AddSC_mulgore()
newscript->Name="npc_skorn_whitecloud";
newscript->pGossipHello = &GossipHello_npc_skorn_whitecloud;
newscript->pGossipSelect = &GossipSelect_npc_skorn_whitecloud;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp b/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
index dcd3f57bef3..f662fe4c2c4 100644
--- a/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
+++ b/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
@@ -631,46 +631,46 @@ void AddSC_nagrand()
newscript = new Script;
newscript->Name="mob_shattered_rumbler";
newscript->GetAI = GetAI_mob_shattered_rumbler;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_lump";
newscript->GetAI = GetAI_mob_lump;
newscript->pGossipHello = &GossipHello_mob_lump;
newscript->pGossipSelect = &GossipSelect_mob_lump;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_sunspring_villager";
newscript->GetAI = GetAI_mob_sunspring_villager;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_altruis_the_sufferer";
newscript->pGossipHello = &GossipHello_npc_altruis_the_sufferer;
newscript->pGossipSelect = &GossipSelect_npc_altruis_the_sufferer;
newscript->pQuestAccept = &QuestAccept_npc_altruis_the_sufferer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_greatmother_geyah";
newscript->pGossipHello = &GossipHello_npc_greatmother_geyah;
newscript->pGossipSelect = &GossipSelect_npc_greatmother_geyah;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_lantresor_of_the_blade";
newscript->pGossipHello = &GossipHello_npc_lantresor_of_the_blade;
newscript->pGossipSelect = &GossipSelect_npc_lantresor_of_the_blade;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_creditmarker_visit_with_ancestors";
newscript->GetAI = GetAI_npc_creditmarker_visit_with_ancestors;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_sparrowhawk";
newscript->GetAI = GetAI_mob_sparrowhawk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp
index 50a4f867b4c..2b93e7828f9 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp
@@ -208,5 +208,5 @@ void AddSC_boss_anubrekhan()
newscript = new Script;
newscript->Name="boss_anubrekhan";
newscript->GetAI = GetAI_boss_anubrekhan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp
index 4add49e17b4..dbcf72510aa 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp
@@ -197,5 +197,5 @@ void AddSC_boss_faerlina()
newscript = new Script;
newscript->Name="boss_faerlina";
newscript->GetAI = GetAI_boss_faerlina;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp
index 09e3c1ecf25..b5b40a4b245 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gluth.cpp
@@ -170,5 +170,5 @@ void AddSC_boss_gluth()
newscript = new Script;
newscript->Name="boss_gluth";
newscript->GetAI = GetAI_boss_gluth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_highlord_mograine.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_highlord_mograine.cpp
index 96d94ad51ad..d21e2a2119f 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_highlord_mograine.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_highlord_mograine.cpp
@@ -174,5 +174,5 @@ void AddSC_boss_highlord_mograine()
newscript = new Script;
newscript->Name="boss_highlord_mograine";
newscript->GetAI = GetAI_boss_highlord_mograine;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp
index 3a47f6f5c27..e65bfb62fdd 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_kelthuzad.cpp
@@ -537,6 +537,6 @@ void AddSC_boss_kelthuzad()
newscript = new Script;
newscript->Name="boss_kelthuzad";
newscript->GetAI = GetAI_boss_kelthuzadAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
*/
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_lady_blaumeux.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_lady_blaumeux.cpp
index ee3b47e478d..770f880557d 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_lady_blaumeux.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_lady_blaumeux.cpp
@@ -143,5 +143,5 @@ void AddSC_boss_lady_blaumeux()
newscript = new Script;
newscript->Name="boss_lady_blaumeux";
newscript->GetAI = GetAI_boss_lady_blaumeux;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp
index 56fe786e6c8..4da5c6626cb 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_loatheb.cpp
@@ -212,5 +212,5 @@ void AddSC_boss_loatheb()
newscript = new Script;
newscript->Name="boss_loatheb";
newscript->GetAI = GetAI_boss_loatheb;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp
index 4c65feb9c7b..821ca832e65 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp
@@ -237,10 +237,10 @@ void AddSC_boss_maexxna()
newscript = new Script;
newscript->Name="boss_maexxna";
newscript->GetAI = GetAI_boss_maexxna;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_webwrap";
newscript->GetAI = GetAI_mob_webwrap;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp
index cda01c57e40..43616311bb4 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp
@@ -176,5 +176,5 @@ void AddSC_boss_noth()
newscript = new Script;
newscript->Name="boss_noth";
newscript->GetAI = GetAI_boss_noth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
index d0edc7f46b3..2f51c9c3064 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
@@ -156,5 +156,5 @@ void AddSC_boss_patchwerk()
newscript = new Script;
newscript->Name="boss_patchwerk";
newscript->GetAI = GetAI_boss_patchwerk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp
index d83f99bda43..ac7de1db7eb 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp
@@ -163,5 +163,5 @@ void AddSC_boss_razuvious()
newscript = new Script;
newscript->Name="boss_razuvious";
newscript->GetAI = GetAI_boss_razuvious;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
index 0be1619ad74..75a2f20db14 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
@@ -195,5 +195,5 @@ void AddSC_boss_sapphiron()
newscript = new Script;
newscript->Name="boss_sapphiron";
newscript->GetAI = GetAI_boss_sapphiron;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sir_zeliek.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sir_zeliek.cpp
index 0a3ca7a951b..8dead488208 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sir_zeliek.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sir_zeliek.cpp
@@ -142,5 +142,5 @@ void AddSC_boss_sir_zeliek()
newscript = new Script;
newscript->Name="boss_sir_zeliek";
newscript->GetAI = GetAI_boss_sir_zeliek;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_thane_korthazz.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_thane_korthazz.cpp
index a040626258d..500f0955316 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_thane_korthazz.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_thane_korthazz.cpp
@@ -143,5 +143,5 @@ void AddSC_boss_thane_korthazz()
newscript = new Script;
newscript->Name="boss_thane_korthazz";
newscript->GetAI = GetAI_boss_thane_korthazz;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
index 2d35802338e..4125c4e888e 100644
--- a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
+++ b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
@@ -400,22 +400,22 @@ void AddSC_netherstorm()
newscript = new Script;
newscript->Name="go_manaforge_control_console";
newscript->pGOHello = &GOHello_go_manaforge_control_console;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_manaforge_control_console";
newscript->GetAI = GetAI_npc_manaforge_control_console;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_protectorate_nether_drake";
newscript->pGossipHello = &GossipHello_npc_protectorate_nether_drake;
newscript->pGossipSelect = &GossipSelect_npc_protectorate_nether_drake;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_veronia";
newscript->pGossipHello = &GossipHello_npc_veronia;
newscript->pGossipSelect = &GossipSelect_npc_veronia;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp b/src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp
index 7774f65411d..eb73f8bfb3a 100644
--- a/src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp
+++ b/src/bindings/scripts/scripts/zone/onyxias_lair/boss_onyxia.cpp
@@ -229,5 +229,5 @@ void AddSC_boss_onyxia()
newscript = new Script;
newscript->Name="boss_onyxia";
newscript->GetAI = GetAI_boss_onyxiaAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp b/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp
index cb4be0499fc..76c7a5f3416 100644
--- a/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp
+++ b/src/bindings/scripts/scripts/zone/orgrimmar/orgrimmar.cpp
@@ -247,19 +247,19 @@ void AddSC_orgrimmar()
newscript->Name="npc_neeru_fireblade";
newscript->pGossipHello = &GossipHello_npc_neeru_fireblade;
newscript->pGossipSelect = &GossipSelect_npc_neeru_fireblade;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_shenthul";
newscript->GetAI = GetAI_npc_shenthul;
newscript->pQuestAccept = &QuestAccept_npc_shenthul;
newscript->pReceiveEmote = &ReciveEmote_npc_shenthul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_thrall_warchief";
newscript->GetAI = GetAI_npc_thrall_warchief;
newscript->pGossipHello = &GossipHello_npc_thrall_warchief;
newscript->pGossipSelect = &GossipSelect_npc_thrall_warchief;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp b/src/bindings/scripts/scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp
index 163db1c2756..e7f3184a60e 100644
--- a/src/bindings/scripts/scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp
+++ b/src/bindings/scripts/scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp
@@ -136,5 +136,5 @@ void AddSC_boss_amnennar_the_coldbringer()
newscript = new Script;
newscript->Name="boss_amnennar_the_coldbringer";
newscript->GetAI = GetAI_boss_amnennar_the_coldbringer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp
index 03a53d50297..374daab3344 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp
@@ -103,5 +103,5 @@ void AddSC_boss_ayamiss()
newscript = new Script;
newscript->Name="boss_ayamiss";
newscript->GetAI = GetAI_boss_ayamiss;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp
index 3a287d8b6ae..124ebccbcbb 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp
@@ -89,5 +89,5 @@ void AddSC_boss_kurinnaxx()
newscript = new Script;
newscript->Name="boss_kurinnaxx";
newscript->GetAI = GetAI_boss_kurinnaxx;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp
index 836dd3f8065..12e58066456 100644
--- a/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp
+++ b/src/bindings/scripts/scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp
@@ -113,5 +113,5 @@ void AddSC_boss_moam()
newscript = new Script;
newscript->Name="boss_moam";
newscript->GetAI = GetAI_boss_moam;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp
index 50764c4d022..aaa156b8092 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp
@@ -167,5 +167,5 @@ void AddSC_boss_arcanist_doan()
newscript = new Script;
newscript->Name="boss_arcanist_doan";
newscript->GetAI = GetAI_boss_arcanist_doan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp
index 4ea395a8038..10d340eae91 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp
@@ -93,5 +93,5 @@ void AddSC_boss_azshir_the_sleepless()
newscript = new Script;
newscript->Name="boss_azshir_the_sleepless";
newscript->GetAI = GetAI_boss_azshir_the_sleepless;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp
index 9fa5bee9714..ae2324d8615 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp
@@ -132,5 +132,5 @@ void AddSC_boss_bloodmage_thalnos()
newscript = new Script;
newscript->Name="boss_bloodmage_thalnos";
newscript->GetAI = GetAI_boss_bloodmage_thalnos;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp
index de1fd991c33..494def37c11 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_herod.cpp
@@ -193,5 +193,5 @@ void AddSC_boss_herod()
newscript = new Script;
newscript->Name="boss_herod";
newscript->GetAI = GetAI_boss_herod;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp
index 5742214e31d..a230629b871 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp
@@ -128,5 +128,5 @@ void AddSC_boss_high_inquisitor_fairbanks()
newscript = new Script;
newscript->Name="boss_high_inquisitor_fairbanks";
newscript->GetAI = GetAI_boss_high_inquisitor_fairbanks;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_whitemane.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_whitemane.cpp
index 97fbce31b01..c10da64c4e9 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_whitemane.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_high_inquisitor_whitemane.cpp
@@ -173,5 +173,5 @@ void AddSC_boss_high_inquisitor_whitemane()
newscript = new Script;
newscript->Name="boss_high_inquisitor_whitemane";
newscript->GetAI = GetAI_boss_high_inquisitor_whitemane;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp
index 6353f600460..e268d25c9d7 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp
@@ -74,5 +74,5 @@ void AddSC_boss_houndmaster_loksey()
newscript = new Script;
newscript->Name="boss_houndmaster_loksey";
newscript->GetAI = GetAI_boss_houndmaster_loksey;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp
index ede58d0997e..98cb742eb01 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp
@@ -109,5 +109,5 @@ void AddSC_boss_interrogator_vishas()
newscript = new Script;
newscript->Name="boss_interrogator_vishas";
newscript->GetAI = GetAI_boss_interrogator_vishas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scarlet_commander_mograine.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scarlet_commander_mograine.cpp
index 5e87b1a2b77..1d8587d9f78 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scarlet_commander_mograine.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scarlet_commander_mograine.cpp
@@ -156,5 +156,5 @@ void AddSC_boss_scarlet_commander_mograine()
newscript = new Script;
newscript->Name="boss_scarlet_commander_mograine";
newscript->GetAI = GetAI_boss_scarlet_commander_mograine;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp
index 1f9e3fb2487..95a206d1657 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_scorn.cpp
@@ -96,5 +96,5 @@ void AddSC_boss_scorn()
newscript = new Script;
newscript->Name="boss_scorn";
newscript->GetAI = GetAI_boss_scorn;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
index f67bf9fe594..38e6ad85d8c 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
@@ -188,5 +188,5 @@ void AddSC_boss_darkmaster_gandling()
newscript = new Script;
newscript->Name="boss_darkmaster_gandling";
newscript->GetAI = GetAI_boss_darkmaster_gandling;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_death_knight_darkreaver.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_death_knight_darkreaver.cpp
index 747ec039363..fa410af2734 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_death_knight_darkreaver.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_death_knight_darkreaver.cpp
@@ -55,5 +55,5 @@ void AddSC_boss_death_knight_darkreaver()
newscript = new Script;
newscript->Name="boss_death_knight_darkreaver";
newscript->GetAI = GetAI_boss_death_knight_darkreaver;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp
index 484a27dca98..3993a58f1cd 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp
@@ -104,5 +104,5 @@ void AddSC_boss_theolenkrastinov()
newscript = new Script;
newscript->Name="boss_doctor_theolen_krastinov";
newscript->GetAI = GetAI_boss_theolenkrastinov;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp
index 1edae02fcf3..4b871f8e173 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_illucia_barov.cpp
@@ -112,5 +112,5 @@ void AddSC_boss_illuciabarov()
newscript = new Script;
newscript->Name="boss_illucia_barov";
newscript->GetAI = GetAI_boss_illuciabarov;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp
index 705b2835843..15e5c93a982 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_instructor_malicia.cpp
@@ -148,5 +148,5 @@ void AddSC_boss_instructormalicia()
newscript = new Script;
newscript->Name="boss_instructor_malicia";
newscript->GetAI = GetAI_boss_instructormalicia;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
index dfae0432d12..e27dc31879e 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
@@ -212,10 +212,10 @@ void AddSC_boss_jandicebarov()
newscript = new Script;
newscript->Name="boss_jandice_barov";
newscript->GetAI = GetAI_boss_jandicebarov;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_illusionofjandicebarov";
newscript->GetAI = GetAI_mob_illusionofjandicebarov;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp
index b3cc6fd0530..1e1fb1ef685 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_kormok.cpp
@@ -151,5 +151,5 @@ void AddSC_boss_kormok()
newscript = new Script;
newscript->Name="boss_kormok";
newscript->GetAI = GetAI_boss_kormok;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_lord_alexei_barov.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_lord_alexei_barov.cpp
index 49f3f733949..8d8f248aede 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_lord_alexei_barov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_lord_alexei_barov.cpp
@@ -94,5 +94,5 @@ void AddSC_boss_lordalexeibarov()
newscript = new Script;
newscript->Name="boss_lord_alexei_barov";
newscript->GetAI = GetAI_boss_lordalexeibarov;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp
index d17d2036d91..c05e4d64d1d 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp
@@ -109,5 +109,5 @@ void AddSC_boss_lorekeeperpolkelt()
newscript = new Script;
newscript->Name="boss_lorekeeper_polkelt";
newscript->GetAI = GetAI_boss_lorekeeperpolkelt;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp
index 0ea243c2d08..afe7eb8716a 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_ras_frostwhisper.cpp
@@ -121,5 +121,5 @@ void AddSC_boss_rasfrost()
newscript = new Script;
newscript->Name="boss_boss_ras_frostwhisper";
newscript->GetAI = GetAI_boss_rasfrost;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp
index f27e8aa458f..d16b0f917ce 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_the_ravenian.cpp
@@ -114,5 +114,5 @@ void AddSC_boss_theravenian()
newscript = new Script;
newscript->Name="boss_the_ravenian";
newscript->GetAI = GetAI_boss_theravenian;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp
index 954ee3b4eba..f92ae0732e1 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_vectus.cpp
@@ -91,5 +91,5 @@ void AddSC_boss_vectus()
newscript = new Script;
newscript->Name="boss_vectus";
newscript->GetAI = GetAI_boss_vectus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp b/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp
index a48537068f8..036a34cd8fa 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/instance_scholomance.cpp
@@ -98,5 +98,5 @@ void AddSC_instance_scholomance()
newscript = new Script;
newscript->Name = "instance_scholomance";
newscript->GetInstanceData = GetInstanceData_instance_scholomance;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp b/src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp
index 7a9ef1a5449..23281eb9050 100644
--- a/src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp
+++ b/src/bindings/scripts/scripts/zone/searing_gorge/searing_gorge.cpp
@@ -143,17 +143,17 @@ void AddSC_searing_gorge()
newscript->Name="npc_kalaran_windblade";
newscript->pGossipHello = &GossipHello_npc_kalaran_windblade;
newscript->pGossipSelect = &GossipSelect_npc_kalaran_windblade;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_lothos_riftwaker";
newscript->pGossipHello = &GossipHello_npc_lothos_riftwaker;
newscript->pGossipSelect = &GossipSelect_npc_lothos_riftwaker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_zamael_lunthistle";
newscript->pGossipHello = &GossipHello_npc_zamael_lunthistle;
newscript->pGossipSelect = &GossipSelect_npc_zamael_lunthistle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp
index dfae8457abc..a854cc96989 100644
--- a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp
@@ -148,5 +148,5 @@ void AddSC_instance_shadowfang_keep()
newscript = new Script;
newscript->Name = "instance_shadowfang_keep";
newscript->GetInstanceData = GetInstanceData_instance_shadowfang_keep;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
index 65e1eaea8ba..d297ccbcdeb 100644
--- a/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
@@ -113,5 +113,5 @@ void AddSC_shadowfang_keep()
newscript->pGossipHello = &GossipHello_npc_shadowfang_prisoner;
newscript->pGossipSelect = &GossipSelect_npc_shadowfang_prisoner;
newscript->GetAI = GetAI_npc_shadowfang_prisoner;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp b/src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp
index 89536b15ac2..a67318bc41c 100644
--- a/src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowmoon_valley/boss_doomwalker.cpp
@@ -212,5 +212,5 @@ void AddSC_boss_doomwalker()
newscript = new Script;
newscript->Name="boss_doomwalker";
newscript->GetAI = GetAI_boss_doomwalker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp b/src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp
index 7bc1ad312a9..534a853302d 100644
--- a/src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp
@@ -1106,73 +1106,73 @@ void AddSC_shadowmoon_valley()
newscript = new Script;
newscript->Name = "mob_mature_netherwing_drake";
newscript->GetAI = GetAI_mob_mature_netherwing_drake;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_enslaved_netherwing_drake";
newscript->GetAI = GetAI_mob_enslaved_netherwing_drake;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_dragonmaw_peon";
newscript->GetAI = GetAI_mob_dragonmaw_peon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_drake_dealer_hurlunk";
newscript->pGossipHello = &GossipHello_npc_drake_dealer_hurlunk;
newscript->pGossipSelect = &GossipSelect_npc_drake_dealer_hurlunk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_invis_legion_teleporter";
newscript->GetAI = GetAI_npc_invis_legion_teleporter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npcs_flanis_swiftwing_and_kagrosh";
newscript->pGossipHello = &GossipHello_npcs_flanis_swiftwing_and_kagrosh;
newscript->pGossipSelect = &GossipSelect_npcs_flanis_swiftwing_and_kagrosh;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_murkblood_overseer";
newscript->pGossipHello = &GossipHello_npc_murkblood_overseer;
newscript->pGossipSelect = &GossipSelect_npc_murkblood_overseer;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_neltharaku";
newscript->pGossipHello = &GossipHello_npc_neltharaku;
newscript->pGossipSelect = &GossipSelect_npc_neltharaku;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_karynaku";
newscript->pQuestAccept = &QuestAccept_npc_karynaku;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_oronok_tornheart";
newscript->pGossipHello = &GossipHello_npc_oronok_tornheart;
newscript->pGossipSelect = &GossipSelect_npc_oronok_tornheart;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_overlord_morghor";
newscript->GetAI = GetAI_Overlord_Morghor;
newscript->pQuestAccept = &QuestAccept_Overlord_Morghor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_lord_illidan_stormrage";
newscript->GetAI = GetAI_Lord_Illidan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_yarzill_the_merc";
newscript->GetAI = GetAI_Yarzill_The_Merc;
newscript->pGossipHello = &GossipHello_npc_yarzill_fly;
newscript->pGossipSelect = &GossipSelect_npc_yarzill_fly;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp
index 41cb56585ef..f974e0ec16d 100644
--- a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp
+++ b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp
@@ -414,28 +414,28 @@ void AddSC_shattrath_city()
newscript->Name="npc_raliq_the_drunk";
newscript->pGossipHello = &GossipHello_npc_raliq_the_drunk;
newscript->pGossipSelect = &GossipSelect_npc_raliq_the_drunk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_salsalabim";
newscript->GetAI = GetAI_npc_salsalabim;
newscript->pGossipHello = &GossipHello_npc_salsalabim;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_shattrathflaskvendors";
newscript->pGossipHello = &GossipHello_npc_shattrathflaskvendors;
newscript->pGossipSelect = &GossipSelect_npc_shattrathflaskvendors;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_zephyr";
newscript->pGossipHello = &GossipHello_npc_zephyr;
newscript->pGossipSelect = &GossipSelect_npc_zephyr;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_kservant";
newscript->GetAI = GetAI_npc_kservantAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/silithus/silithus.cpp b/src/bindings/scripts/scripts/zone/silithus/silithus.cpp
index 5e05fa60630..bf868318342 100644
--- a/src/bindings/scripts/scripts/zone/silithus/silithus.cpp
+++ b/src/bindings/scripts/scripts/zone/silithus/silithus.cpp
@@ -145,5 +145,5 @@ void AddSC_silithus()
newscript->Name="npcs_rutgar_and_frankal";
newscript->pGossipHello = &GossipHello_npcs_rutgar_and_frankal;
newscript->pGossipSelect = &GossipSelect_npcs_rutgar_and_frankal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp b/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp
index 077c078b64a..d50a1fcbdf8 100644
--- a/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp
+++ b/src/bindings/scripts/scripts/zone/silvermoon/silvermoon_city.cpp
@@ -99,5 +99,5 @@ void AddSC_silvermoon_city()
newscript = new Script;
newscript->Name="npc_blood_knight_stillblade";
newscript->GetAI = GetAI_npc_blood_knight_stillblade;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp b/src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp
index 597ab1ccb8d..b511ccbba4e 100644
--- a/src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/silverpine_forest/silverpine_forest.cpp
@@ -96,5 +96,5 @@ void AddSC_silverpine_forest()
newscript->pGossipHello = &GossipHello_npc_astor_hadren;
newscript->pGossipSelect = &GossipSelect_npc_astor_hadren;
newscript->GetAI = GetAI_npc_astor_hadren;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp b/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp
index 40cb6367379..28f0c644726 100644
--- a/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp
+++ b/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp
@@ -76,5 +76,5 @@ void AddSC_stonetalon_mountains()
newscript->Name="npc_braug_dimspirit";
newscript->pGossipHello = &GossipHello_npc_braug_dimspirit;
newscript->pGossipSelect = &GossipSelect_npc_braug_dimspirit;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
index b84b1d98cb6..9c34ec3d926 100644
--- a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
+++ b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
@@ -245,28 +245,28 @@ void AddSC_stormwind_city()
newscript->Name="npc_archmage_malin";
newscript->pGossipHello = &GossipHello_npc_archmage_malin;
newscript->pGossipSelect = &GossipSelect_npc_archmage_malin;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_bartleby";
newscript->GetAI = GetAI_npc_bartleby;
newscript->pQuestAccept = &QuestAccept_npc_bartleby;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_dashel_stonefist";
newscript->GetAI = GetAI_npc_dashel_stonefist;
newscript->pQuestAccept = &QuestAccept_npc_dashel_stonefist;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_general_marcus_jonathan";
newscript->pReceiveEmote = &ReceiveEmote_npc_general_marcus_jonathan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_lady_katrana_prestor";
newscript->pGossipHello = &GossipHello_npc_lady_katrana_prestor;
newscript->pGossipSelect = &GossipSelect_npc_lady_katrana_prestor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp b/src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp
index 40ff438cbd1..426c56c679d 100644
--- a/src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp
+++ b/src/bindings/scripts/scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp
@@ -103,5 +103,5 @@ void AddSC_stranglethorn_vale()
newscript = new Script;
newscript->Name = "mob_yenniku";
newscript->GetAI = GetAI_mob_yenniku;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp
index d3cfa97be75..aac9c590c97 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_baron_rivendare.cpp
@@ -211,5 +211,5 @@ void AddSC_boss_baron_rivendare()
newscript = new Script;
newscript->Name="boss_baron_rivendare";
newscript->GetAI = GetAI_boss_baron_rivendare;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp
index f1315e66b83..8c88353878c 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_baroness_anastari.cpp
@@ -120,5 +120,5 @@ void AddSC_boss_baroness_anastari()
newscript = new Script;
newscript->Name="boss_baroness_anastari";
newscript->GetAI = GetAI_boss_baroness_anastari;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_cannon_master_willey.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_cannon_master_willey.cpp
index 4c1bd05b432..d3e1c4e2a3a 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_cannon_master_willey.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_cannon_master_willey.cpp
@@ -217,5 +217,5 @@ void AddSC_boss_cannon_master_willey()
newscript = new Script;
newscript->Name="boss_cannon_master_willey";
newscript->GetAI = GetAI_boss_cannon_master_willey;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
index 3d084fe0736..67503358d9d 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
@@ -312,5 +312,5 @@ void AddSC_boss_dathrohan_balnazzar()
newscript = new Script;
newscript->Name="boss_dathrohan_balnazzar";
newscript->GetAI = GetAI_boss_dathrohan_balnazzar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp
index cbea76cf205..daa8da39a67 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_magistrate_barthilas.cpp
@@ -110,5 +110,5 @@ void AddSC_boss_magistrate_barthilas()
newscript = new Script;
newscript->Name="boss_magistrate_barthilas";
newscript->GetAI = GetAI_boss_magistrate_barthilas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_maleki_the_pallid.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_maleki_the_pallid.cpp
index e0f9c43cba7..d3d60121a87 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_maleki_the_pallid.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_maleki_the_pallid.cpp
@@ -115,5 +115,5 @@ void AddSC_boss_maleki_the_pallid()
newscript = new Script;
newscript->Name="boss_maleki_the_pallid";
newscript->GetAI = GetAI_boss_maleki_the_pallid;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp
index 3929f2513dd..b56e643bdb2 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_nerubenkan.cpp
@@ -134,5 +134,5 @@ void AddSC_boss_nerubenkan()
newscript = new Script;
newscript->Name="boss_nerubenkan";
newscript->GetAI = GetAI_boss_nerubenkan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_order_of_silver_hand.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_order_of_silver_hand.cpp
index a76913b658c..ee92be7737d 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_order_of_silver_hand.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_order_of_silver_hand.cpp
@@ -157,5 +157,5 @@ void AddSC_boss_order_of_silver_hand()
newscript = new Script;
newscript->Name="boss_silver_hand_bosses";
newscript->GetAI = GetAI_boss_silver_hand_bossesAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp
index a4eddd46b5e..d0514bd2eb8 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_postmaster_malown.cpp
@@ -140,5 +140,5 @@ void AddSC_boss_postmaster_malown()
newscript = new Script;
newscript->Name="boss_postmaster_malown";
newscript->GetAI = GetAI_boss_postmaster_malown;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_ramstein_the_gorger.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_ramstein_the_gorger.cpp
index 674d4403266..b2965f09edf 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_ramstein_the_gorger.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_ramstein_the_gorger.cpp
@@ -88,5 +88,5 @@ void AddSC_boss_ramstein_the_gorger()
newscript = new Script;
newscript->Name="boss_ramstein_the_gorger";
newscript->GetAI = GetAI_boss_ramstein_the_gorger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_timmy_the_cruel.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_timmy_the_cruel.cpp
index 2256c064e11..4f526041e35 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_timmy_the_cruel.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_timmy_the_cruel.cpp
@@ -96,5 +96,5 @@ void AddSC_boss_timmy_the_cruel()
newscript = new Script;
newscript->Name="boss_timmy_the_cruel";
newscript->GetAI = GetAI_boss_timmy_the_cruel;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp b/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp
index eff4edf91a8..74181d6a15e 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/instance_stratholme.cpp
@@ -73,5 +73,5 @@ void AddSC_instance_stratholme()
newscript = new Script;
newscript->Name = "instance_stratholme";
newscript->GetInstanceData = GetInstanceData_instance_stratholme;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp b/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp
index 5097648a04a..2a38abe9311 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/stratholme.cpp
@@ -310,26 +310,26 @@ void AddSC_stratholme()
newscript = new Script;
newscript->Name="mob_freed_soul";
newscript->GetAI = GetAI_mob_freed_soul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_restless_soul";
newscript->GetAI = GetAI_mob_restless_soul;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mobs_spectral_ghostly_citizen";
newscript->GetAI = GetAI_mobs_spectral_ghostly_citizen;
newscript->pReceiveEmote = &ReciveEmote_mobs_spectral_ghostly_citizen;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_mindless_skeleton";
newscript->GetAI = GetAI_mob_mindless_skeleton;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_thuzadin_acolyte";
newscript->GetAI = GetAI_mob_thuzadin_acolyte;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
index fc1bca5233f..24ce8dc4a91 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
@@ -178,5 +178,5 @@ void AddSC_boss_brutallus()
newscript = new Script;
newscript->Name="boss_brutallus";
newscript->GetAI = GetAI_boss_brutallus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp
index b49f0e391f3..b7e076b85d3 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp
@@ -761,15 +761,15 @@ void AddSC_boss_eredar_twins()
newscript = new Script;
newscript->Name="boss_sacrolash";
newscript->GetAI = GetAI_boss_sacrolash;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_alythess";
newscript->GetAI = GetAI_boss_alythess;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_shadow_image";
newscript->GetAI = GetAI_mob_shadow_image;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
index afc95cc8191..9f2b89b44f2 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
@@ -574,15 +574,15 @@ void AddSC_boss_felmyst()
newscript = new Script;
newscript->Name="boss_felmyst";
newscript->GetAI = GetAI_boss_felmyst;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_felmyst_vapor";
newscript->GetAI = GetAI_mob_felmyst_vapor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_felmyst_trail";
newscript->GetAI = GetAI_mob_felmyst_trail;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
index 96a79107296..79d0d3766b8 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
@@ -680,20 +680,20 @@ void AddSC_boss_kalecgos()
newscript = new Script;
newscript->Name="boss_kalecgos";
newscript->GetAI = GetAI_boss_kalecgos;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_sathrovarr";
newscript->GetAI = GetAI_boss_Sathrovarr;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_kalec";
newscript->GetAI = GetAI_boss_kalec;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="kalocegos_teleporter";
newscript->pGOHello = &GOkalocegos_teleporter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
} \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp
index a94cf460a83..98b0bd443b1 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp
@@ -192,5 +192,5 @@ void AddSC_instance_sunwell_plateau()
newscript = new Script;
newscript->Name = "instance_sunwell_plateau";
newscript->GetInstanceData = GetInstanceData_instance_sunwell_plateau;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp b/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp
index 2eb6ab80335..c6700af3e67 100644
--- a/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp
+++ b/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp
@@ -374,29 +374,29 @@ void AddSC_tanaris()
newscript = new Script;
newscript->Name="mob_aquementas";
newscript->GetAI = GetAI_mob_aquementas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_custodian_of_time";
newscript->GetAI = GetAI_npc_custodian_of_time;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_marin_noggenfogger";
newscript->pGossipHello = &GossipHello_npc_marin_noggenfogger;
newscript->pGossipSelect = &GossipSelect_npc_marin_noggenfogger;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_steward_of_time";
newscript->pGossipHello = &GossipHello_npc_steward_of_time;
newscript->pGossipSelect = &GossipSelect_npc_steward_of_time;
newscript->pQuestAccept = &QuestAccept_npc_steward_of_time;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_stone_watcher_of_norgannon";
newscript->pGossipHello = &GossipHello_npc_stone_watcher_of_norgannon;
newscript->pGossipSelect = &GossipSelect_npc_stone_watcher_of_norgannon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp
index f928a41e1e0..624ad419243 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/arcatraz.cpp
@@ -575,15 +575,15 @@ void AddSC_arcatraz()
newscript = new Script;
newscript->Name="npc_millhouse_manastorm";
newscript->GetAI = GetAI_npc_millhouse_manastorm;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_warden_mellichar";
newscript->GetAI = GetAI_npc_warden_mellichar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_zerekethvoidzone";
newscript->GetAI = GetAI_mob_zerekethvoidzoneAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp
index fcd8cf2c607..808604d2375 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp
@@ -367,10 +367,10 @@ void AddSC_boss_harbinger_skyriss()
newscript = new Script;
newscript->Name="boss_harbinger_skyriss";
newscript->GetAI = GetAI_boss_harbinger_skyriss;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_harbinger_skyriss_illusion";
newscript->GetAI = GetAI_boss_harbinger_skyriss_illusion;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp
index 93f21f2a72f..2325680d53b 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp
@@ -220,5 +220,5 @@ void AddSC_instance_arcatraz()
newscript = new Script;
newscript->Name = "instance_arcatraz";
newscript->GetInstanceData = GetInstanceData_instance_arcatraz;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp
index 201b5936ee9..334fdf07b98 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp
@@ -211,5 +211,5 @@ void AddSC_boss_high_botanist_freywinn()
newscript = new Script;
newscript->Name="boss_high_botanist_freywinn";
newscript->GetAI = GetAI_boss_high_botanist_freywinn;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp
index c714c470c55..09a237f53cf 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp
@@ -194,5 +194,5 @@ void AddSC_boss_laj()
newscript = new Script;
newscript->Name="boss_laj";
newscript->GetAI = GetAI_boss_laj;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp
index 5f7c87adff4..f0dc111e896 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp
@@ -293,10 +293,10 @@ void AddSC_boss_warp_splinter()
newscript = new Script;
newscript->Name="boss_warp_splinter";
newscript->GetAI = GetAI_boss_warp_splinter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_warp_splinter_treant";
newscript->GetAI = GetAI_mob_treant;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
index 617fd29dbc2..138d3d19f99 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
@@ -505,15 +505,15 @@ void AddSC_boss_alar()
newscript = new Script;
newscript->Name="boss_alar";
newscript->GetAI = GetAI_boss_alar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_ember_of_alar";
newscript->GetAI = GetAI_mob_ember_of_alar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_flame_patch_alar";
newscript->GetAI = GetAI_mob_flame_patch_alar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp
index 477aab20241..9e93eac4693 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp
@@ -536,10 +536,10 @@ void AddSC_boss_high_astromancer_solarian()
newscript = new Script;
newscript->Name="boss_high_astromancer_solarian";
newscript->GetAI = GetAI_boss_high_astromancer_solarian;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_solarium_priest";
newscript->GetAI = GetAI_mob_solarium_priest;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp
index ddbfbb65bf2..ca5d8dcf7dd 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp
@@ -1581,35 +1581,35 @@ void AddSC_boss_kaelthas()
newscript = new Script;
newscript->Name="boss_kaelthas";
newscript->GetAI = GetAI_boss_kaelthas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_thaladred_the_darkener";
newscript->GetAI = GetAI_boss_thaladred_the_darkener;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lord_sanguinar";
newscript->GetAI = GetAI_boss_lord_sanguinar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_grand_astromancer_capernian";
newscript->GetAI = GetAI_boss_grand_astromancer_capernian;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_master_engineer_telonicus";
newscript->GetAI = GetAI_boss_master_engineer_telonicus;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name= "mob_kael_flamestrike";
newscript->GetAI = GetAI_mob_kael_flamestrike;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_phoenix";
newscript->GetAI = GetAI_mob_phoenix;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
index 406e7e4d9ab..de6335e79e3 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
@@ -195,5 +195,5 @@ void AddSC_boss_void_reaver()
newscript = new Script;
newscript->Name="boss_void_reaver";
newscript->GetAI = GetAI_boss_void_reaver;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp
index 3f1316d45e8..1fa1030a991 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp
@@ -172,5 +172,5 @@ void AddSC_instance_the_eye()
newscript = new Script;
newscript->Name = "instance_the_eye";
newscript->GetInstanceData = GetInstanceData_instance_the_eye;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/the_eye.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/the_eye.cpp
index cd2962b509a..18d37e88bdc 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/the_eye.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/the_eye.cpp
@@ -94,5 +94,5 @@ void AddSC_the_eye()
newscript = new Script;
newscript->Name="mob_crystalcore_devastator";
newscript->GetAI = GetAI_mob_crystalcore_devastator;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp
index 90ec4076d21..dfc5d70bb42 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp
@@ -157,5 +157,5 @@ void AddSC_boss_gatewatcher_iron_hand()
newscript = new Script;
newscript->Name="boss_gatewatcher_iron_hand";
newscript->GetAI = GetAI_boss_gatewatcher_iron_hand;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp
index 866f641922c..d077f5b8c0c 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp
@@ -277,10 +277,10 @@ void AddSC_boss_nethermancer_sepethrea()
newscript = new Script;
newscript->Name="boss_nethermancer_sepethrea";
newscript->GetAI = GetAI_boss_nethermancer_sepethrea;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_ragin_flames";
newscript->GetAI = GetAI_mob_ragin_flames;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp
index 06c57082357..91ceea65cdd 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp
@@ -297,10 +297,10 @@ void AddSC_boss_pathaleon_the_calculator()
newscript = new Script;
newscript->Name="boss_pathaleon_the_calculator";
newscript->GetAI = GetAI_boss_pathaleon_the_calculator;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_nether_wraith";
newscript->GetAI = GetAI_mob_nether_wraith;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp
index c58ab523b90..4ea1fcfad5b 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_mechanar/instance_mechanar.cpp
@@ -86,5 +86,5 @@ void AddSC_instance_mechanar()
newscript = new Script;
newscript->Name = "instance_mechanar";
newscript->GetInstanceData = GetInstanceData_instance_mechanar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp
index 1dba25cd132..8f2f025f7f1 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp
@@ -334,15 +334,15 @@ void AddSC_bug_trio()
newscript = new Script;
newscript->Name="boss_kri";
newscript->GetAI = GetAI_boss_kri;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_vem";
newscript->GetAI = GetAI_boss_vem;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_yauj";
newscript->GetAI = GetAI_boss_yauj;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp
index 3548cf92566..b789f68e9aa 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp
@@ -1329,35 +1329,35 @@ void AddSC_boss_cthun()
newscript = new Script;
newscript->Name="boss_eye_of_cthun";
newscript->GetAI = GetAI_eye_of_cthun;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_cthun";
newscript->GetAI = GetAI_cthun;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_eye_tentacle";
newscript->GetAI = GetAI_eye_tentacle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_claw_tentacle";
newscript->GetAI = GetAI_claw_tentacle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_giant_claw_tentacle";
newscript->GetAI = GetAI_giant_claw_tentacle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_giant_eye_tentacle";
newscript->GetAI = GetAI_giant_eye_tentacle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_giant_flesh_tentacle";
newscript->GetAI = GetAI_flesh_tentacle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp
index 331e43d83ef..babd0ebf7c2 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp
@@ -186,5 +186,5 @@ void AddSC_boss_fankriss()
newscript = new Script;
newscript->Name="boss_fankriss";
newscript->GetAI = GetAI_boss_fankriss;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp
index 7fb10528dff..51e030fa49d 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp
@@ -139,5 +139,5 @@ void AddSC_boss_huhuran()
newscript = new Script;
newscript->Name="boss_huhuran";
newscript->GetAI = GetAI_boss_huhuran;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp
index df7efb8f123..1e0e8fbca6d 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp
@@ -136,5 +136,5 @@ void AddSC_boss_ouro()
newscript = new Script;
newscript->Name="boss_ouro";
newscript->GetAI = GetAI_boss_ouro;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp
index 3315e49732c..c9a732493f7 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp
@@ -259,10 +259,10 @@ void AddSC_boss_sartura()
newscript = new Script;
newscript->Name="boss_sartura";
newscript->GetAI = GetAI_boss_sartura;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_sartura_royal_guard";
newscript->GetAI = GetAI_mob_sartura_royal_guard;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp
index 9d383ef0d61..9194354ddc0 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp
@@ -310,5 +310,5 @@ void AddSC_boss_skeram()
newscript = new Script;
newscript->Name="boss_skeram";
newscript->GetAI = GetAI_boss_skeram;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
index 2ddb8be73c7..93525ad7246 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
@@ -689,10 +689,10 @@ void AddSC_boss_twinemperors()
newscript = new Script;
newscript->Name="boss_veknilash";
newscript->GetAI = GetAI_boss_veknilash;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_veklor";
newscript->GetAI = GetAI_boss_veklor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp
index f502b2aa23d..84713b190cf 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp
@@ -161,5 +161,5 @@ void AddSC_instance_temple_of_ahnqiraj()
newscript = new Script;
newscript->Name = "instance_temple_of_ahnqiraj";
newscript->GetInstanceData = GetInstanceData_instance_temple_of_ahnqiraj;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
index 1c009721428..f5a55d711b7 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
@@ -309,7 +309,7 @@ void AddSC_mob_anubisath_sentinel()
newscript = new Script;
newscript->Name="mob_anubisath_sentinel";
newscript->GetAI = GetAI_mob_anubisath_sentinelAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
SentinelAbilityAura::~SentinelAbilityAura() {}
diff --git a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
index d38b7186172..d84c3c58133 100644
--- a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
@@ -368,32 +368,32 @@ void AddSC_terokkar_forest()
newscript = new Script;
newscript->Name="mob_unkor_the_ruthless";
newscript->GetAI = GetAI_mob_unkor_the_ruthless;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_infested_root_walker";
newscript->GetAI = GetAI_mob_infested_root_walker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_rotting_forest_rager";
newscript->GetAI = GetAI_mob_rotting_forest_rager;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_netherweb_victim";
newscript->GetAI = GetAI_mob_netherweb_victim;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_floon";
newscript->pGossipHello = &GossipHello_npc_floon;
newscript->pGossipSelect = &GossipSelect_npc_floon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_skyguard_handler_deesak";
newscript->pGossipHello = &GossipHello_npc_skyguard_handler_deesak;
newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_deesak;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp b/src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp
index ae65bd9d232..4b7dcd5a84a 100644
--- a/src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp
+++ b/src/bindings/scripts/scripts/zone/thunder_bluff/thunder_bluff.cpp
@@ -132,5 +132,5 @@ void AddSC_thunder_bluff()
newscript->GetAI = GetAI_npc_cairne_bloodhoof;
newscript->pGossipHello = &GossipHello_npc_cairne_bloodhoof;
newscript->pGossipSelect = &GossipSelect_npc_cairne_bloodhoof;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
index f95bc029752..d037b2b7e14 100644
--- a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
+++ b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
@@ -84,5 +84,5 @@ void AddSC_tirisfal_glades()
newscript->Name="npc_calvin_montague";
newscript->GetAI = GetAI_npc_calvin_montague;
newscript->pQuestAccept = &QuestAccept_npc_calvin_montague;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp b/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp
index 34f8fda78cf..db4b7c22df3 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/boss_ironaya.cpp
@@ -103,5 +103,5 @@ void AddSC_boss_ironaya()
newscript = new Script;
newscript->Name="boss_ironaya";
newscript->GetAI = GetAI_boss_ironaya;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp b/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp
index 1e1a6eb8462..e8453db9f65 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/uldaman.cpp
@@ -177,11 +177,11 @@ void AddSC_uldaman()
newscript = new Script;
newscript->Name="mob_jadespine_basilisk";
newscript->GetAI = GetAI_mob_jadespine_basilisk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_lore_keeper_of_norgannon";
newscript->pGossipHello = &GossipHello_npc_lore_keeper_of_norgannon;
newscript->pGossipSelect = &GossipSelect_npc_lore_keeper_of_norgannon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/undercity/undercity.cpp b/src/bindings/scripts/scripts/zone/undercity/undercity.cpp
index b395121c73c..89ded786ce5 100644
--- a/src/bindings/scripts/scripts/zone/undercity/undercity.cpp
+++ b/src/bindings/scripts/scripts/zone/undercity/undercity.cpp
@@ -245,16 +245,16 @@ void AddSC_undercity()
newscript->Name="npc_lady_sylvanas_windrunner";
newscript->GetAI = GetAI_npc_lady_sylvanas_windrunner;
newscript->pChooseReward = &ChooseReward_npc_lady_sylvanas_windrunner;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_highborne_lamenter";
newscript->GetAI = GetAI_npc_highborne_lamenter;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_parqual_fintallas";
newscript->pGossipHello = &GossipHello_npc_parqual_fintallas;
newscript->pGossipSelect = &GossipSelect_npc_parqual_fintallas;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp b/src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp
index c3725b0afc9..3f8dee012f4 100644
--- a/src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp
+++ b/src/bindings/scripts/scripts/zone/western_plaguelands/western_plaguelands.cpp
@@ -167,10 +167,10 @@ void AddSC_western_plaguelands()
newscript->Name="npcs_dithers_and_arbington";
newscript->pGossipHello = &GossipHello_npcs_dithers_and_arbington;
newscript->pGossipSelect = &GossipSelect_npcs_dithers_and_arbington;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_the_scourge_cauldron";
newscript->GetAI = GetAI_npc_the_scourge_cauldron;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/westfall/westfall.cpp b/src/bindings/scripts/scripts/zone/westfall/westfall.cpp
index 446f71f1c56..b311bf674eb 100644
--- a/src/bindings/scripts/scripts/zone/westfall/westfall.cpp
+++ b/src/bindings/scripts/scripts/zone/westfall/westfall.cpp
@@ -175,5 +175,5 @@ void AddSC_westfall()
newscript->Name="npc_defias_traitor";
newscript->GetAI = &GetAI_npc_defias_traitor;
newscript->pQuestAccept = &QuestAccept_npc_defias_traitor;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp b/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp
index 7d6f8ea30fb..08ead2eb1de 100644
--- a/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp
+++ b/src/bindings/scripts/scripts/zone/winterspring/winterspring.cpp
@@ -141,17 +141,17 @@ void AddSC_winterspring()
newscript->Name="npc_lorax";
newscript->pGossipHello = &GossipHello_npc_lorax;
newscript->pGossipSelect = &GossipSelect_npc_lorax;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_rivern_frostwind";
newscript->pGossipHello = &GossipHello_npc_rivern_frostwind;
newscript->pGossipSelect = &GossipSelect_npc_rivern_frostwind;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_witch_doctor_mauari";
newscript->pGossipHello = &GossipHello_npc_witch_doctor_mauari;
newscript->pGossipSelect = &GossipSelect_npc_witch_doctor_mauari;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp b/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp
index 621d3e5da49..fdce0029e9d 100644
--- a/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp
+++ b/src/bindings/scripts/scripts/zone/zangarmarsh/zangarmarsh.cpp
@@ -261,23 +261,23 @@ void AddSC_zangarmarsh()
newscript->Name="npcs_ashyen_and_keleth";
newscript->pGossipHello = &GossipHello_npcs_ashyen_and_keleth;
newscript->pGossipSelect = &GossipSelect_npcs_ashyen_and_keleth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_cooshcoosh";
newscript->pGossipHello = &GossipHello_npc_cooshcoosh;
newscript->pGossipSelect = &GossipSelect_npc_cooshcoosh;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_elder_kuruti";
newscript->pGossipHello = &GossipHello_npc_elder_kuruti;
newscript->pGossipSelect = &GossipSelect_npc_elder_kuruti;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_mortog_steamhead";
newscript->pGossipHello = &GossipHello_npc_mortog_steamhead;
newscript->pGossipSelect = &GossipSelect_npc_mortog_steamhead;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
index c7327376ae1..4b9eb2afa88 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
@@ -461,10 +461,10 @@ void AddSC_boss_akilzon()
newscript = new Script;
newscript->Name="boss_akilzon";
newscript->GetAI = GetAI_boss_akilzon;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_akilzon_eagle";
newscript->GetAI = GetAI_mob_soaring_eagle;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp
index 8daab23c6b2..19235677831 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_halazzi.cpp
@@ -394,10 +394,10 @@ void AddSC_boss_halazzi()
newscript = new Script;
newscript->Name="boss_halazzi";
newscript->GetAI = GetAI_boss_halazziAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_halazzi_lynx";
newscript->GetAI = GetAI_boss_spiritlynxAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
index 781a0c812ba..4d36a138765 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
@@ -868,45 +868,45 @@ void AddSC_boss_hex_lord_malacrass()
newscript = new Script;
newscript->Name="boss_hexlord_malacrass";
newscript->GetAI = GetAI_boss_hex_lord_malacrass;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_thurg";
newscript->GetAI = GetAI_boss_thurg;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_gazakroth";
newscript->GetAI = GetAI_boss_gazakroth;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_lord_raadan";
newscript->GetAI = GetAI_boss_lord_raadan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_darkheart";
newscript->GetAI = GetAI_boss_darkheart;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_slither";
newscript->GetAI = GetAI_boss_slither;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_fenstalker";
newscript->GetAI = GetAI_boss_fenstalker;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_koragg";
newscript->GetAI = GetAI_boss_koragg;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="boss_alyson_antille";
newscript->GetAI = GetAI_boss_alyson_antille;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
} \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
index 8cc7efb233b..463425a5ef3 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
@@ -706,25 +706,25 @@ void AddSC_boss_janalai()
newscript = new Script;
newscript->Name="boss_janalai";
newscript->GetAI = GetAI_boss_janalaiAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_janalai_firebomb";
newscript->GetAI = GetAI_mob_jandalai_firebombAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_janalai_hatcher";
newscript->GetAI = GetAI_mob_amanishi_hatcherAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_janalai_hatchling";
newscript->GetAI = GetAI_mob_hatchlingAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_janalai_egg";
newscript->GetAI = GetAI_mob_eggAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
index d51e1cdfa00..359bf496043 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
@@ -300,5 +300,5 @@ void AddSC_boss_nalorakk()
newscript = new Script;
newscript->Name="boss_nalorakk";
newscript->GetAI = GetAI_boss_nalorakk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
index 0b41f591d06..2fa0b83432a 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
@@ -629,15 +629,15 @@ void AddSC_boss_zuljin()
newscript = new Script;
newscript->Name="boss_zuljin";
newscript->GetAI = GetAI_boss_zuljin;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="do_nothing";
newscript->GetAI = GetAI_do_nothing;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_zuljin_vortex";
newscript->GetAI = GetAI_feather_vortexAI;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
index 2abf2d8becf..c0c68c1a2e4 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
@@ -147,11 +147,11 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance
{
if(!QuestMinute)
return;
-
- Map::PlayerList const &PlayerList = instance->GetPlayers();
- if (PlayerList.isEmpty())
- return;
-
+
+ Map::PlayerList const &PlayerList = instance->GetPlayers();
+ if (PlayerList.isEmpty())
+ return;
+
Map::PlayerList::const_iterator i = PlayerList.begin();
if(Player* i_pl = i->getSource())
{
@@ -328,5 +328,5 @@ void AddSC_instance_zulaman()
newscript = new Script;
newscript->Name = "instance_zulaman";
newscript->GetInstanceData = GetInstanceData_instance_zulaman;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp
index 4927ff4869a..b28b8a9bd06 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/zulaman.cpp
@@ -171,12 +171,12 @@ void AddSC_zulaman()
newscript = new Script;
newscript->Name="npc_forest_frog";
newscript->GetAI = GetAI_npc_forest_frog;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_zulaman_hostage";
newscript->GetAI = GetAI_npc_zulaman_hostage;
newscript->pGossipHello = GossipHello_npc_zulaman_hostage;
newscript->pGossipSelect = GossipSelect_npc_zulaman_hostage;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp b/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp
index 6145f640634..a385314a12d 100644
--- a/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp
+++ b/src/bindings/scripts/scripts/zone/zulfarrak/zulfarrak.cpp
@@ -213,12 +213,12 @@ void AddSC_zulfarrak()
newscript->GetAI = GetAI_npc_sergeant_bly;
newscript->pGossipHello = &GossipHello_npc_sergeant_bly;
newscript->pGossipSelect = &GossipSelect_npc_sergeant_bly;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_weegli_blastfuse";
newscript->GetAI = GetAI_npc_weegli_blastfuse;
newscript->pGossipHello = &GossipHello_npc_weegli_blastfuse;
newscript->pGossipSelect = &GossipSelect_npc_weegli_blastfuse;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
index e32538616f6..0d08f35c6a1 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
@@ -207,5 +207,5 @@ void AddSC_boss_arlokk()
newscript = new Script;
newscript->Name="boss_arlokk";
newscript->GetAI = GetAI_boss_arlokk;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp
index 7168d647d49..bcbd8287c46 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_gahzranka.cpp
@@ -88,5 +88,5 @@ void AddSC_boss_gahzranka()
newscript = new Script;
newscript->Name="boss_gahzranka";
newscript->GetAI = GetAI_boss_gahzranka;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
index c882aa3ae6f..d9ab005a8d5 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
@@ -88,5 +88,5 @@ void AddSC_boss_grilek()
newscript = new Script;
newscript->Name="boss_grilek";
newscript->GetAI = GetAI_boss_grilek;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp
index cdd4c42128b..93db797e25f 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_hakkar.cpp
@@ -252,5 +252,5 @@ void AddSC_boss_hakkar()
newscript = new Script;
newscript->Name="boss_hakkar";
newscript->GetAI = GetAI_boss_hakkar;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp
index 62140f5303d..166e5bb0467 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_hazzarah.cpp
@@ -96,5 +96,5 @@ void AddSC_boss_hazzarah()
newscript = new Script;
newscript->Name="boss_hazzarah";
newscript->GetAI = GetAI_boss_hazzarah;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp
index 86b6068cb3a..ce63d6f1587 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_jeklik.cpp
@@ -288,10 +288,10 @@ void AddSC_boss_jeklik()
newscript = new Script;
newscript->Name="boss_jeklik";
newscript->GetAI = GetAI_boss_jeklik;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_batrider";
newscript->GetAI = GetAI_mob_batrider;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
index a5752845b92..f133cc6bceb 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
@@ -258,15 +258,15 @@ void AddSC_boss_jindo()
newscript = new Script;
newscript->Name="boss_jindo";
newscript->GetAI = GetAI_boss_jindo;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_healing_ward";
newscript->GetAI = GetAI_mob_healing_ward;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_shade_of_jindo";
newscript->GetAI = GetAI_mob_shade_of_jindo;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp
index 9781fae1f2d..a70f39e2210 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_mandokir.cpp
@@ -302,10 +302,10 @@ void AddSC_boss_mandokir()
newscript = new Script;
newscript->Name="boss_mandokir";
newscript->GetAI = GetAI_boss_mandokir;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_ohgan";
newscript->GetAI = GetAI_mob_ohgan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
index de9a440ba38..5f276a6c3f8 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
@@ -244,10 +244,10 @@ void AddSC_boss_marli()
newscript = new Script;
newscript->Name="boss_marli";
newscript->GetAI = GetAI_boss_marli;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_spawn_of_marli";
newscript->GetAI = GetAI_mob_spawn_of_marli;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
index ada5cc6cdbc..7febe276dc1 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
@@ -147,5 +147,5 @@ void AddSC_boss_renataki()
newscript = new Script;
newscript->Name="boss_renataki";
newscript->GetAI = GetAI_boss_renataki;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
index b1b44f9b94d..0eebbc1dda6 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
@@ -531,15 +531,15 @@ void AddSC_boss_thekal()
newscript = new Script;
newscript->Name="boss_thekal";
newscript->GetAI = GetAI_boss_thekal;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_zealot_lorkhan";
newscript->GetAI = GetAI_mob_zealot_lorkhan;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_zealot_zath";
newscript->GetAI = GetAI_mob_zealot_zath;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp
index 771b61c372f..3d8657d1b67 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_venoxis.cpp
@@ -196,5 +196,5 @@ void AddSC_boss_venoxis()
newscript = new Script;
newscript->Name="boss_venoxis";
newscript->GetAI = GetAI_boss_venoxis;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp
index 3ac05c97b04..83e682917ae 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_wushoolay.cpp
@@ -80,5 +80,5 @@ void AddSC_boss_wushoolay()
newscript = new Script;
newscript->Name="boss_wushoolay";
newscript->GetAI = GetAI_boss_wushoolay;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp b/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp
index 501c200fa5c..0e9a14a05b9 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/instance_zulgurub.cpp
@@ -234,5 +234,5 @@ void AddSC_instance_zulgurub()
newscript = new Script;
newscript->Name = "instance_zulgurub";
newscript->GetInstanceData = GetInstanceData_instance_zulgurub;
- m_scripts[nrscripts++] = newscript;
+ newscript->RegisterSelf();
}
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp
index b108c98e1ec..b8f38f88f52 100644
--- a/src/game/ArenaTeam.cpp
+++ b/src/game/ArenaTeam.cpp
@@ -1,796 +1,796 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "WorldPacket.h"
-#include "ObjectMgr.h"
-#include "ArenaTeam.h"
-
-ArenaTeam::ArenaTeam()
-{
- Id = 0;
- Type = 0;
- Name = "";
- CaptainGuid = 0;
- BackgroundColor = 0; // background
- EmblemStyle = 0; // icon
- EmblemColor = 0; // icon color
- BorderStyle = 0; // border
- BorderColor = 0; // border color
- stats.games = 0;
- stats.played = 0;
- stats.rank = 0;
- stats.rating = 1500;
- stats.wins = 0;
- stats.wins2 = 0;
-}
-
-ArenaTeam::~ArenaTeam()
-{
-
-}
-
-bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
-{
- if(!objmgr.GetPlayer(captainGuid)) // player not exist
- return false;
- if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist
- return false;
-
- sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
-
- CaptainGuid = captainGuid;
- Name = ArenaTeamName;
- Type = type;
-
- QueryResult *result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
- if( result )
- {
- Id = (*result)[0].GetUInt32()+1;
- delete result;
- }
- else Id = 1;
-
- // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
- CharacterDatabase.escape_string(ArenaTeamName);
-
- CharacterDatabase.BeginTransaction();
- // CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", Id); - MAX(arenateam)+1 not exist
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id);
- CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
- "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
- Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor);
- CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
- "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games,stats.wins,stats.played,stats.wins2,stats.rank);
-
- CharacterDatabase.CommitTransaction();
-
- AddMember(CaptainGuid);
- return true;
-}
-
-bool ArenaTeam::AddMember(uint64 PlayerGuid)
-{
- std::string plName;
- uint8 plClass;
-
- // arena team is full (can't have more than type * 2 players!)
- if(GetMembersSize() >= GetType() * 2)
- return false;
-
- Player *pl = objmgr.GetPlayer(PlayerGuid);
- if(pl)
- {
- if(pl->GetArenaTeamId(GetSlot()))
- {
- sLog.outError("Arena::AddMember() : player already in this sized team");
- return false;
- }
-
- plClass = (uint8)pl->getClass();
- plName = pl->GetName();
- }
- else
- {
- // 0 1
- QueryResult *result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
- if(!result)
- return false;
-
- plName = (*result)[0].GetCppString();
- plClass = (*result)[1].GetUInt8();
- delete result;
-
- // check if player already in arenateam of that size
- if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
- {
- sLog.outError("Arena::AddMember() : player already in this sized team");
- return false;
- }
- }
-
- // remove all player signs from another petitions
- // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
- Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
-
- ArenaTeamMember newmember;
- newmember.name = plName;
- newmember.guid = PlayerGuid;
- newmember.Class = plClass;
- newmember.played_season = 0;
- newmember.played_week = 0;
- newmember.wons_season = 0;
- newmember.wons_week = 0;
- members.push_back(newmember);
-
- CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid));
-
- if(pl)
- {
- pl->SetInArenaTeam(Id, GetSlot());
- pl->SetArenaTeamIdInvited(0);
- // personal rating
- pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500);
- }
-
- // hide promote/remove buttons
- if(CaptainGuid != PlayerGuid)
- {
- if(pl)
- pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
- }
-
- // setuint32valueindb is asynch, can't be used here
- Tokens tokens;
- if(!Player::LoadValuesArrayFromDB(tokens,PlayerGuid))
- return false;
-
- // arena team id
- uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6);
- char buf[11];
- snprintf(buf,11,"%u",Id);
- tokens[index] = buf;
- // pers rating
- index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5;
- buf[11];
- snprintf(buf,11,"%u",1500);
- tokens[index] = buf;
- // hide promote/remove buttons
- if(CaptainGuid != PlayerGuid)
- {
- index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6);
- buf[11];
- snprintf(buf,11,"%u",1);
- tokens[index] = buf;
- }
-
- Player::SaveValuesArrayInDB(tokens,PlayerGuid);
-
- return true;
-}
-
-bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
-{
- QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
-
- if(!result)
- return false;
-
- Field *fields = result->Fetch();
-
- Id = fields[0].GetUInt32();
- Name = fields[1].GetCppString();
- CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
- Type = fields[3].GetUInt32();
- BackgroundColor = fields[4].GetUInt32();
- EmblemStyle = fields[5].GetUInt32();
- EmblemColor = fields[6].GetUInt32();
- BorderStyle = fields[7].GetUInt32();
- BorderColor = fields[8].GetUInt32();
-
- delete result;
-
- // only load here, so additional checks can be made
- LoadStatsFromDB(ArenaTeamId);
- LoadMembersFromDB(ArenaTeamId);
-
- if(!GetMembersSize())
- {
- // arena team is empty, delete from db
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
- CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
- CharacterDatabase.CommitTransaction();
- // return false
- return false;
- }
-
- return true;
-}
-
-void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
-{
- // 0 1 2 3 4 5
- QueryResult *result = CharacterDatabase.PQuery("SELECT rating,games,wins,played,wins2,rank FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
-
- if(!result)
- return;
-
- Field *fields = result->Fetch();
-
- stats.rating = fields[0].GetUInt32();
- stats.games = fields[1].GetUInt32();
- stats.wins = fields[2].GetUInt32();
- stats.played = fields[3].GetUInt32();
- stats.wins2 = fields[4].GetUInt32();
- stats.rank = fields[5].GetUInt32();
-
- delete result;
-}
-
-void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
-{
- Field *fields;
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT guid,played_week,wons_week,played_season,wons_season,points_to_add FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
- if(!result)
- return;
-
- do
- {
- fields = result->Fetch();
- ArenaTeamMember newmember;
- newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
- // check if this member is in this arenateam
- // based on character data field
- if(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6),newmember.guid) != ArenaTeamId)
- {
- // the player's registered arena team for this slot isn't this team, so delete member info from here
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u' AND arenateamid = '%u'",fields[0].GetUInt32(), ArenaTeamId);
- continue;
- }
- LoadPlayerStats(&newmember);
- newmember.played_week = fields[1].GetUInt32();
- newmember.wons_week = fields[2].GetUInt32();
- newmember.played_season = fields[3].GetUInt32();
- newmember.wons_season = fields[4].GetUInt32();
- members.push_back(newmember);
- }while( result->NextRow() );
- delete result;
-}
-
-void ArenaTeam::LoadPlayerStats(ArenaTeamMember *member)
-{
- Field *fields;
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT name,class FROM characters WHERE guid = '%u'", GUID_LOPART(member->guid));
- if(!result)
- return;
- fields = result->Fetch();
- member->name = fields[0].GetCppString();
- member->Class = fields[1].GetUInt8();
-
- delete result;
-}
-
-void ArenaTeam::SetCaptain(uint64 guid)
-{
- // disable remove/promote buttons
- Player *oldcaptain = objmgr.GetPlayer(GetCaptain());
- if(oldcaptain)
- oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
- else
- Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, GetCaptain());
-
- // set new captain
- CaptainGuid = guid;
-
- // update database
- CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), Id);
-
- // enable remove/promote buttons
- Player *newcaptain = objmgr.GetPlayer(guid);
- if(newcaptain)
- newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0);
- else
- Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0, guid);
-}
-
-void ArenaTeam::DelMember(uint64 guid)
-{
- MemberList::iterator itr;
- for (itr = members.begin(); itr != members.end(); itr++)
- {
- if (itr->guid == guid)
- {
- members.erase(itr);
- break;
- }
- }
-
- Player *player = objmgr.GetPlayer(guid);
- // this will be ugly. because of the asynchronous sql handling, we have to set all the fields of the player at once, and save them at once, or else the save will only modify the last field.
- // rip off of setuint32valueindb
- if(player)
- {
- player->SetInArenaTeam(0, GetSlot());
- player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
- // delete all info regarding this team
- for(int i = 0; i < 6; ++i)
- {
- player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i, 0);
- }
- }
-
- // we have to do it this way, setuint32valueindb is asynch, unsafe to use multiple times in a row on the same player
- Tokens tokens;
- if(!Player::LoadValuesArrayFromDB(tokens,guid))
- return;
-
- for(int i = 0; i < 6; ++i)
- {
- uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i;
- char buf[11];
- snprintf(buf,11,"%u",0);
- tokens[index] = buf;
- }
-
- Player::SaveValuesArrayInDB(tokens,guid);
-
- // only delete from this arena team!
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid));
-}
-
-void ArenaTeam::Disband(WorldSession *session)
-{
- // event
- WorldPacket data;
- session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), "");
- BroadcastPacket(&data);
-
- uint32 count = members.size();
- uint64 *memberGuids = new uint64[count];
-
- MemberList::iterator itr;
- uint32 i=0;
- for(itr = members.begin(); itr != members.end(); itr++)
- {
- memberGuids[i] = itr->guid;
- ++i;
- }
-
- for(uint32 j = 0; j < count; j++)
- DelMember(memberGuids[j]);
- delete[] memberGuids;
-
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id);
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", Id);
- CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id);
- CharacterDatabase.CommitTransaction();
- objmgr.RemoveArenaTeam(this);
-}
-
-void ArenaTeam::Roster(WorldSession *session)
-{
- Player *pl = NULL;
-
- WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
- data << uint32(GetId()); // arena team id
- data << uint32(GetMembersSize()); // members count
- data << uint32(GetType()); // arena team type?
-
- for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- pl = objmgr.GetPlayer(itr->guid);
- if(pl)
- {
- data << uint64(pl->GetGUID()); // guid
- data << uint8(1); // online flag
- data << pl->GetName(); // member name
- data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
- data << uint8(pl->getLevel()); // unknown, probably level
- data << uint8(pl->getClass()); // class
- data << uint32(itr->played_week); // played this week
- data << uint32(itr->wons_week); // wins this week
- data << uint32(itr->played_season); // played this season
- data << uint32(itr->wons_season); // wins this season
- data << uint32(pl->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5)); // personal rating?
- }
- else
- {
- data << uint64(itr->guid); // guid
- data << uint8(0); // online flag
- data << itr->name; // member name
- data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
- data << uint8(0); // unknown, level?
- data << uint8(itr->Class); // class
- data << uint32(itr->played_week); // played this week
- data << uint32(itr->wons_week); // wins this week
- data << uint32(itr->played_season); // played this season
- data << uint32(itr->wons_season); // wins this season
- data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, itr->guid)); // personal rating?
- }
- }
- session->SendPacket(&data);
- sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
-}
-
-void ArenaTeam::Query(WorldSession *session)
-{
- WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
- data << uint32(GetId()); // team id
- data << GetName(); // team name
- data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
- data << uint32(BackgroundColor); // background color
- data << uint32(EmblemStyle); // emblem style
- data << uint32(EmblemColor); // emblem color
- data << uint32(BorderStyle); // border style
- data << uint32(BorderColor); // border color
- session->SendPacket(&data);
- sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
-}
-
-void ArenaTeam::Stats(WorldSession *session)
-{
- WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
- data << uint32(GetId()); // arena team id
- data << uint32(stats.rating); // rating
- data << uint32(stats.games); // games
- data << uint32(stats.wins); // wins
- data << uint32(stats.played); // played
- data << uint32(stats.wins2); // wins(again o_O)
- data << uint32(stats.rank); // rank
- session->SendPacket(&data);
-}
-
-void ArenaTeam::NotifyStatsChanged()
-{
- // this is called after a rated match ended
- // updates arena team stats for every member of the team (not only the ones who participated!)
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- Player * plr=objmgr.GetPlayer(itr->guid);
- if(plr)
- Stats(plr->GetSession());
- }
-}
-
-void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
-{
- WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
- data << uint64(guid); // player guid
- data << uint8(GetSlot()); // slot (0...2)
- data << uint32(GetId()); // arena team id
- data << uint32(stats.rating); // rating
- data << uint32(stats.played); // season played
- data << uint32(stats.wins2); // season wins
- uint32 participated = 0;
- for(MemberList::iterator itr = members.begin(); itr!= members.end(); ++itr)
- {
- if(itr->guid == guid)
- {
- participated = itr->played_season;
- break;
- }
- }
- data << uint32(participated); // played (count of all games, that the inspected member participated...)
- data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, guid)); // unk, 2.3.3 (personal rating?)
-
- session->SendPacket(&data);
-}
-
-void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
-{
- BackgroundColor = backgroundColor;
- EmblemStyle = emblemStyle;
- EmblemColor = emblemColor;
- BorderStyle = borderStyle;
- BorderColor = borderColor;
-
- CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor, Id);
-}
-
-void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
-{
- switch(stat_type)
- {
- case STAT_TYPE_RATING:
- stats.rating = value;
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId());
- break;
- case STAT_TYPE_GAMES:
- stats.games = value;
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId());
- break;
- case STAT_TYPE_WINS:
- stats.wins = value;
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId());
- break;
- case STAT_TYPE_PLAYED:
- stats.played = value;
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId());
- break;
- case STAT_TYPE_WINS2:
- stats.wins2 = value;
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId());
- break;
- case STAT_TYPE_RANK:
- stats.rank = value;
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId());
- break;
- default:
- sLog.outDebug("unknown stat type in ArenaTeam::SetStats() %u", stat_type);
- break;
- }
-}
-
-uint8 ArenaTeam::GetSlot() const
-{
- uint8 slot = GetSlotByType(GetType());
- if(slot >= MAX_ARENA_SLOT)
- {
- sLog.outError("Unknown arena team type %u for arena team %u", uint32(GetType()), GetId());
- return 0; // better return existed slot to prevent untelated data curruption
- }
-
- return slot;
-}
-
-void ArenaTeam::BroadcastPacket(WorldPacket *packet)
-{
- for (MemberList::iterator itr = members.begin(); itr != members.end(); itr++)
- {
- Player *player = objmgr.GetPlayer(itr->guid);
- if(player)
- player->GetSession()->SendPacket(packet);
- }
-}
-
-uint8 ArenaTeam::GetSlotByType( uint32 type )
-{
- switch(type)
- {
- case ARENA_TEAM_2v2: return 0;
- case ARENA_TEAM_3v3: return 1;
- case ARENA_TEAM_5v5: return 2;
- default:
- break;
- }
- return 0xFF;
-}
-
-bool ArenaTeam::HaveMember( uint64 guid ) const
-{
- for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
- if(itr->guid==guid)
- return true;
-
- return false;
-}
-
-uint32 ArenaTeam::GetPoints(uint32 MemberRating)
-{
- // returns how many points would be awarded with this team type with this rating
- float points;
-
- uint32 rating = MemberRating + 150 < stats.rating ? MemberRating : stats.rating;
-
- if(rating<=1500)
- {
- points = (float)rating * 0.22f + 14.0f;
- }
- else
- {
- points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
- }
-
- // type penalties for <5v5 teams
- if(Type == ARENA_TEAM_2v2)
- points *= 0.76f;
- else if(Type == ARENA_TEAM_3v3)
- points *= 0.88f;
-
- return (uint32) points;
-}
-
-float ArenaTeam::GetChanceAgainst(uint32 rating)
-{
- // returns the chance to win against a team with the given rating, used in the rating adjustment calculation
- // ELO system
- return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)rating - (float)stats.rating)/400.0f));
-}
-
-int32 ArenaTeam::WonAgainstChance(float chance)
-{
- // called when the team has won, and had 'chance' calculated chance to beat the opponent
- // calculate the rating modification (ELO system with k=32)
- int32 mod = (int32)floor(32.0f * (1.0f - chance));
- // modify the team stats accordingly
- stats.rating += mod;
- stats.games += 1;
- stats.wins += 1;
- stats.played += 1;
- stats.wins2 += 1;
-/* this should be done in .flusharenapoints; not a breaker though.
- uint32 higher_rank = 0;
- QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT(arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id);
- if(result)
- {
- higher_rank = result->Fetch()->GetUInt32();
- delete result;
- }
- stats.rank = higher_rank + 1;*/
- // return the rating change, used to display it on the results screen
- return mod;
-}
-
-int32 ArenaTeam::LostAgainstChance(float chance)
-{
- // called when the team has lost, and had 'chance' calculated chance to beat the opponent
- // calculate the rating modification (ELO system with k=32)
- int32 mod = (int32)ceil(32.0f * (0.0f - chance));
- // modify the team stats accordingly
- stats.rating += mod;
- stats.games += 1;
- stats.played += 1;
-/* uint32 higher_rank = 0;
- QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT (arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id);
- if(result)
- {
- higher_rank = result->Fetch()->GetUInt32();
- delete result;
- }
- stats.rank = higher_rank + 1;*/
- // return the rating adjustment for display
- return mod;
-}
-
-void ArenaTeam::MemberLost(Player * plr, uint32 againstrating)
-{
- // called for each participant of a match after losing
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- if(itr->guid == plr->GetGUID())
- {
- // update personal rating
- int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5);
- float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f));
- int32 mod = (int32)ceil(32.0f * (0.0f - chance));
- personalrating += mod;
- if(personalrating < 0)
- personalrating = 0;
- plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating);
- // update personal played stats
- itr->played_week +=1;
- itr->played_season +=1;
- // update the unit fields
- plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->played_week);
- plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->played_season);
- return;
- }
- }
-}
-
-void ArenaTeam::MemberWon(Player * plr, uint32 againstrating)
-{
- // called for each participant after winning a match
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- if(itr->guid == plr->GetGUID())
- {
- // update personal rating
- int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5);
- float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f));
- int32 mod = (int32)floor(32.0f * (1.0f - chance));
- personalrating += mod;
- if(personalrating < 0)
- personalrating = 0;
- plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating);
- // update personal stats
- itr->played_week +=1;
- itr->played_season +=1;
- itr->wons_season += 1;
- itr->wons_week += 1;
- // update unit fields
- plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->played_week);
- plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->played_season);
- return;
- }
- }
-}
-
-void ArenaTeam::UpdateArenaPointsHelper()
-{
- // called after a match has ended and the stats are already modified
- // helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
- // 10 played games per week is a minimum
- if(stats.games < 10)
- return;
- // to get points, a player has to participate in at least 30% of the matches
- uint32 min_plays = (uint32)ceil(stats.games * 0.3);
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- // the player participated in enough games, update his points
- if(itr->played_week >= min_plays)
- {
- // do it separately for online and offline players
- // online players might have modified personal rating in MemberLost/MemberWon, that's not already saved to DB because of asynch queries
- // offline player cant have a personal rating not matching the db
- Player * plr = objmgr.GetPlayer(itr->guid);
- uint32 points_to_add = 0;
- if(plr)
- points_to_add = GetPoints(plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5));
- else
- points_to_add = GetPoints(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5,itr->guid));
- // it's enough to set the points in memory, the saving is done in separate function
- CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid);
- }
- // the player failed to participate in enough games, so no points for him
- else
- {
- CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", 0, Id, itr->guid);
- }
- }
-}
-
-void ArenaTeam::SaveToDB()
-{
- // save team and member stats to db
- // called after a match has ended
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", stats.rating, stats.games, stats.played, stats.rank, stats.wins, stats.wins2, GetId());
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->played_week, itr->wons_week, itr->played_season, itr->wons_season, Id, itr->guid);
- }
-}
-
-void ArenaTeam::FinishWeek()
-{
- stats.games = 0; // played this week
- stats.wins = 0; // wins this week
- for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- itr->played_week = 0;
- itr->wons_week = 0;
- }
-}
-
-/*
-arenateam fields (id from 2.3.3 client):
-1414 - arena team id 2v2
-1415 - 0=captain, 1=member
-1416 - played this week
-1417 - played this season
-1418 - unk
-1419 - personal arena rating
-1420 - arena team id 3v3
-1421 - 0=captain, 1=member
-1422 - played this week
-1423 - played this season
-1424 - unk
-1425 - personal arena rating
-1426 - arena team id 5v5
-1427 - 0=captain, 1=member
-1428 - played this week
-1429 - played this season
-1430 - unk
-1431 - personal arena rating
-*/
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "WorldPacket.h"
+#include "ObjectMgr.h"
+#include "ArenaTeam.h"
+
+ArenaTeam::ArenaTeam()
+{
+ Id = 0;
+ Type = 0;
+ Name = "";
+ CaptainGuid = 0;
+ BackgroundColor = 0; // background
+ EmblemStyle = 0; // icon
+ EmblemColor = 0; // icon color
+ BorderStyle = 0; // border
+ BorderColor = 0; // border color
+ stats.games = 0;
+ stats.played = 0;
+ stats.rank = 0;
+ stats.rating = 1500;
+ stats.wins = 0;
+ stats.wins2 = 0;
+}
+
+ArenaTeam::~ArenaTeam()
+{
+
+}
+
+bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
+{
+ if(!objmgr.GetPlayer(captainGuid)) // player not exist
+ return false;
+ if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist
+ return false;
+
+ sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
+
+ CaptainGuid = captainGuid;
+ Name = ArenaTeamName;
+ Type = type;
+
+ QueryResult *result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
+ if( result )
+ {
+ Id = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+ else Id = 1;
+
+ // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
+ CharacterDatabase.escape_string(ArenaTeamName);
+
+ CharacterDatabase.BeginTransaction();
+ // CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", Id); - MAX(arenateam)+1 not exist
+ CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id);
+ CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
+ "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
+ Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor);
+ CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
+ "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games,stats.wins,stats.played,stats.wins2,stats.rank);
+
+ CharacterDatabase.CommitTransaction();
+
+ AddMember(CaptainGuid);
+ return true;
+}
+
+bool ArenaTeam::AddMember(uint64 PlayerGuid)
+{
+ std::string plName;
+ uint8 plClass;
+
+ // arena team is full (can't have more than type * 2 players!)
+ if(GetMembersSize() >= GetType() * 2)
+ return false;
+
+ Player *pl = objmgr.GetPlayer(PlayerGuid);
+ if(pl)
+ {
+ if(pl->GetArenaTeamId(GetSlot()))
+ {
+ sLog.outError("Arena::AddMember() : player already in this sized team");
+ return false;
+ }
+
+ plClass = (uint8)pl->getClass();
+ plName = pl->GetName();
+ }
+ else
+ {
+ // 0 1
+ QueryResult *result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
+ if(!result)
+ return false;
+
+ plName = (*result)[0].GetCppString();
+ plClass = (*result)[1].GetUInt8();
+ delete result;
+
+ // check if player already in arenateam of that size
+ if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
+ {
+ sLog.outError("Arena::AddMember() : player already in this sized team");
+ return false;
+ }
+ }
+
+ // remove all player signs from another petitions
+ // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
+ Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
+
+ ArenaTeamMember newmember;
+ newmember.name = plName;
+ newmember.guid = PlayerGuid;
+ newmember.Class = plClass;
+ newmember.played_season = 0;
+ newmember.played_week = 0;
+ newmember.wons_season = 0;
+ newmember.wons_week = 0;
+ members.push_back(newmember);
+
+ CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid));
+
+ if(pl)
+ {
+ pl->SetInArenaTeam(Id, GetSlot());
+ pl->SetArenaTeamIdInvited(0);
+ // personal rating
+ pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500);
+ }
+
+ // hide promote/remove buttons
+ if(CaptainGuid != PlayerGuid)
+ {
+ if(pl)
+ pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
+ }
+
+ // setuint32valueindb is asynch, can't be used here
+ Tokens tokens;
+ if(!Player::LoadValuesArrayFromDB(tokens,PlayerGuid))
+ return false;
+
+ // arena team id
+ uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6);
+ char buf[11];
+ snprintf(buf,11,"%u",Id);
+ tokens[index] = buf;
+ // pers rating
+ index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5;
+ buf[11];
+ snprintf(buf,11,"%u",1500);
+ tokens[index] = buf;
+ // hide promote/remove buttons
+ if(CaptainGuid != PlayerGuid)
+ {
+ index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6);
+ buf[11];
+ snprintf(buf,11,"%u",1);
+ tokens[index] = buf;
+ }
+
+ Player::SaveValuesArrayInDB(tokens,PlayerGuid);
+
+ return true;
+}
+
+bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
+
+ if(!result)
+ return false;
+
+ Field *fields = result->Fetch();
+
+ Id = fields[0].GetUInt32();
+ Name = fields[1].GetCppString();
+ CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
+ Type = fields[3].GetUInt32();
+ BackgroundColor = fields[4].GetUInt32();
+ EmblemStyle = fields[5].GetUInt32();
+ EmblemColor = fields[6].GetUInt32();
+ BorderStyle = fields[7].GetUInt32();
+ BorderColor = fields[8].GetUInt32();
+
+ delete result;
+
+ // only load here, so additional checks can be made
+ LoadStatsFromDB(ArenaTeamId);
+ LoadMembersFromDB(ArenaTeamId);
+
+ if(!GetMembersSize())
+ {
+ // arena team is empty, delete from db
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
+ CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
+ CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
+ CharacterDatabase.CommitTransaction();
+ // return false
+ return false;
+ }
+
+ return true;
+}
+
+void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
+{
+ // 0 1 2 3 4 5
+ QueryResult *result = CharacterDatabase.PQuery("SELECT rating,games,wins,played,wins2,rank FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
+
+ if(!result)
+ return;
+
+ Field *fields = result->Fetch();
+
+ stats.rating = fields[0].GetUInt32();
+ stats.games = fields[1].GetUInt32();
+ stats.wins = fields[2].GetUInt32();
+ stats.played = fields[3].GetUInt32();
+ stats.wins2 = fields[4].GetUInt32();
+ stats.rank = fields[5].GetUInt32();
+
+ delete result;
+}
+
+void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
+{
+ Field *fields;
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT guid,played_week,wons_week,played_season,wons_season,points_to_add FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
+ if(!result)
+ return;
+
+ do
+ {
+ fields = result->Fetch();
+ ArenaTeamMember newmember;
+ newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ // check if this member is in this arenateam
+ // based on character data field
+ if(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6),newmember.guid) != ArenaTeamId)
+ {
+ // the player's registered arena team for this slot isn't this team, so delete member info from here
+ CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u' AND arenateamid = '%u'",fields[0].GetUInt32(), ArenaTeamId);
+ continue;
+ }
+ LoadPlayerStats(&newmember);
+ newmember.played_week = fields[1].GetUInt32();
+ newmember.wons_week = fields[2].GetUInt32();
+ newmember.played_season = fields[3].GetUInt32();
+ newmember.wons_season = fields[4].GetUInt32();
+ members.push_back(newmember);
+ }while( result->NextRow() );
+ delete result;
+}
+
+void ArenaTeam::LoadPlayerStats(ArenaTeamMember *member)
+{
+ Field *fields;
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT name,class FROM characters WHERE guid = '%u'", GUID_LOPART(member->guid));
+ if(!result)
+ return;
+ fields = result->Fetch();
+ member->name = fields[0].GetCppString();
+ member->Class = fields[1].GetUInt8();
+
+ delete result;
+}
+
+void ArenaTeam::SetCaptain(uint64 guid)
+{
+ // disable remove/promote buttons
+ Player *oldcaptain = objmgr.GetPlayer(GetCaptain());
+ if(oldcaptain)
+ oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
+ else
+ Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, GetCaptain());
+
+ // set new captain
+ CaptainGuid = guid;
+
+ // update database
+ CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), Id);
+
+ // enable remove/promote buttons
+ Player *newcaptain = objmgr.GetPlayer(guid);
+ if(newcaptain)
+ newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0);
+ else
+ Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0, guid);
+}
+
+void ArenaTeam::DelMember(uint64 guid)
+{
+ MemberList::iterator itr;
+ for (itr = members.begin(); itr != members.end(); itr++)
+ {
+ if (itr->guid == guid)
+ {
+ members.erase(itr);
+ break;
+ }
+ }
+
+ Player *player = objmgr.GetPlayer(guid);
+ // this will be ugly. because of the asynchronous sql handling, we have to set all the fields of the player at once, and save them at once, or else the save will only modify the last field.
+ // rip off of setuint32valueindb
+ if(player)
+ {
+ player->SetInArenaTeam(0, GetSlot());
+ player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
+ // delete all info regarding this team
+ for(int i = 0; i < 6; ++i)
+ {
+ player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i, 0);
+ }
+ }
+
+ // we have to do it this way, setuint32valueindb is asynch, unsafe to use multiple times in a row on the same player
+ Tokens tokens;
+ if(!Player::LoadValuesArrayFromDB(tokens,guid))
+ return;
+
+ for(int i = 0; i < 6; ++i)
+ {
+ uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i;
+ char buf[11];
+ snprintf(buf,11,"%u",0);
+ tokens[index] = buf;
+ }
+
+ Player::SaveValuesArrayInDB(tokens,guid);
+
+ // only delete from this arena team!
+ CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid));
+}
+
+void ArenaTeam::Disband(WorldSession *session)
+{
+ // event
+ WorldPacket data;
+ session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), "");
+ BroadcastPacket(&data);
+
+ uint32 count = members.size();
+ uint64 *memberGuids = new uint64[count];
+
+ MemberList::iterator itr;
+ uint32 i=0;
+ for(itr = members.begin(); itr != members.end(); itr++)
+ {
+ memberGuids[i] = itr->guid;
+ ++i;
+ }
+
+ for(uint32 j = 0; j < count; j++)
+ DelMember(memberGuids[j]);
+ delete[] memberGuids;
+
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id);
+ CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", Id);
+ CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id);
+ CharacterDatabase.CommitTransaction();
+ objmgr.RemoveArenaTeam(this);
+}
+
+void ArenaTeam::Roster(WorldSession *session)
+{
+ Player *pl = NULL;
+
+ WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
+ data << uint32(GetId()); // arena team id
+ data << uint32(GetMembersSize()); // members count
+ data << uint32(GetType()); // arena team type?
+
+ for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ pl = objmgr.GetPlayer(itr->guid);
+ if(pl)
+ {
+ data << uint64(pl->GetGUID()); // guid
+ data << uint8(1); // online flag
+ data << pl->GetName(); // member name
+ data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
+ data << uint8(pl->getLevel()); // unknown, probably level
+ data << uint8(pl->getClass()); // class
+ data << uint32(itr->played_week); // played this week
+ data << uint32(itr->wons_week); // wins this week
+ data << uint32(itr->played_season); // played this season
+ data << uint32(itr->wons_season); // wins this season
+ data << uint32(pl->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5)); // personal rating?
+ }
+ else
+ {
+ data << uint64(itr->guid); // guid
+ data << uint8(0); // online flag
+ data << itr->name; // member name
+ data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
+ data << uint8(0); // unknown, level?
+ data << uint8(itr->Class); // class
+ data << uint32(itr->played_week); // played this week
+ data << uint32(itr->wons_week); // wins this week
+ data << uint32(itr->played_season); // played this season
+ data << uint32(itr->wons_season); // wins this season
+ data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, itr->guid)); // personal rating?
+ }
+ }
+ session->SendPacket(&data);
+ sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
+}
+
+void ArenaTeam::Query(WorldSession *session)
+{
+ WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
+ data << uint32(GetId()); // team id
+ data << GetName(); // team name
+ data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
+ data << uint32(BackgroundColor); // background color
+ data << uint32(EmblemStyle); // emblem style
+ data << uint32(EmblemColor); // emblem color
+ data << uint32(BorderStyle); // border style
+ data << uint32(BorderColor); // border color
+ session->SendPacket(&data);
+ sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
+}
+
+void ArenaTeam::Stats(WorldSession *session)
+{
+ WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
+ data << uint32(GetId()); // arena team id
+ data << uint32(stats.rating); // rating
+ data << uint32(stats.games); // games
+ data << uint32(stats.wins); // wins
+ data << uint32(stats.played); // played
+ data << uint32(stats.wins2); // wins(again o_O)
+ data << uint32(stats.rank); // rank
+ session->SendPacket(&data);
+}
+
+void ArenaTeam::NotifyStatsChanged()
+{
+ // this is called after a rated match ended
+ // updates arena team stats for every member of the team (not only the ones who participated!)
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ Player * plr=objmgr.GetPlayer(itr->guid);
+ if(plr)
+ Stats(plr->GetSession());
+ }
+}
+
+void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
+{
+ WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
+ data << uint64(guid); // player guid
+ data << uint8(GetSlot()); // slot (0...2)
+ data << uint32(GetId()); // arena team id
+ data << uint32(stats.rating); // rating
+ data << uint32(stats.played); // season played
+ data << uint32(stats.wins2); // season wins
+ uint32 participated = 0;
+ for(MemberList::iterator itr = members.begin(); itr!= members.end(); ++itr)
+ {
+ if(itr->guid == guid)
+ {
+ participated = itr->played_season;
+ break;
+ }
+ }
+ data << uint32(participated); // played (count of all games, that the inspected member participated...)
+ data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, guid)); // unk, 2.3.3 (personal rating?)
+
+ session->SendPacket(&data);
+}
+
+void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
+{
+ BackgroundColor = backgroundColor;
+ EmblemStyle = emblemStyle;
+ EmblemColor = emblemColor;
+ BorderStyle = borderStyle;
+ BorderColor = borderColor;
+
+ CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor, Id);
+}
+
+void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
+{
+ switch(stat_type)
+ {
+ case STAT_TYPE_RATING:
+ stats.rating = value;
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId());
+ break;
+ case STAT_TYPE_GAMES:
+ stats.games = value;
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId());
+ break;
+ case STAT_TYPE_WINS:
+ stats.wins = value;
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId());
+ break;
+ case STAT_TYPE_PLAYED:
+ stats.played = value;
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId());
+ break;
+ case STAT_TYPE_WINS2:
+ stats.wins2 = value;
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId());
+ break;
+ case STAT_TYPE_RANK:
+ stats.rank = value;
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId());
+ break;
+ default:
+ sLog.outDebug("unknown stat type in ArenaTeam::SetStats() %u", stat_type);
+ break;
+ }
+}
+
+uint8 ArenaTeam::GetSlot() const
+{
+ uint8 slot = GetSlotByType(GetType());
+ if(slot >= MAX_ARENA_SLOT)
+ {
+ sLog.outError("Unknown arena team type %u for arena team %u", uint32(GetType()), GetId());
+ return 0; // better return existed slot to prevent untelated data curruption
+ }
+
+ return slot;
+}
+
+void ArenaTeam::BroadcastPacket(WorldPacket *packet)
+{
+ for (MemberList::iterator itr = members.begin(); itr != members.end(); itr++)
+ {
+ Player *player = objmgr.GetPlayer(itr->guid);
+ if(player)
+ player->GetSession()->SendPacket(packet);
+ }
+}
+
+uint8 ArenaTeam::GetSlotByType( uint32 type )
+{
+ switch(type)
+ {
+ case ARENA_TEAM_2v2: return 0;
+ case ARENA_TEAM_3v3: return 1;
+ case ARENA_TEAM_5v5: return 2;
+ default:
+ break;
+ }
+ return 0xFF;
+}
+
+bool ArenaTeam::HaveMember( uint64 guid ) const
+{
+ for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
+ if(itr->guid==guid)
+ return true;
+
+ return false;
+}
+
+uint32 ArenaTeam::GetPoints(uint32 MemberRating)
+{
+ // returns how many points would be awarded with this team type with this rating
+ float points;
+
+ uint32 rating = MemberRating + 150 < stats.rating ? MemberRating : stats.rating;
+
+ if(rating<=1500)
+ {
+ points = (float)rating * 0.22f + 14.0f;
+ }
+ else
+ {
+ points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
+ }
+
+ // type penalties for <5v5 teams
+ if(Type == ARENA_TEAM_2v2)
+ points *= 0.76f;
+ else if(Type == ARENA_TEAM_3v3)
+ points *= 0.88f;
+
+ return (uint32) points;
+}
+
+float ArenaTeam::GetChanceAgainst(uint32 rating)
+{
+ // returns the chance to win against a team with the given rating, used in the rating adjustment calculation
+ // ELO system
+ return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)rating - (float)stats.rating)/400.0f));
+}
+
+int32 ArenaTeam::WonAgainstChance(float chance)
+{
+ // called when the team has won, and had 'chance' calculated chance to beat the opponent
+ // calculate the rating modification (ELO system with k=32)
+ int32 mod = (int32)floor(32.0f * (1.0f - chance));
+ // modify the team stats accordingly
+ stats.rating += mod;
+ stats.games += 1;
+ stats.wins += 1;
+ stats.played += 1;
+ stats.wins2 += 1;
+/* this should be done in .flusharenapoints; not a breaker though.
+ uint32 higher_rank = 0;
+ QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT(arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id);
+ if(result)
+ {
+ higher_rank = result->Fetch()->GetUInt32();
+ delete result;
+ }
+ stats.rank = higher_rank + 1;*/
+ // return the rating change, used to display it on the results screen
+ return mod;
+}
+
+int32 ArenaTeam::LostAgainstChance(float chance)
+{
+ // called when the team has lost, and had 'chance' calculated chance to beat the opponent
+ // calculate the rating modification (ELO system with k=32)
+ int32 mod = (int32)ceil(32.0f * (0.0f - chance));
+ // modify the team stats accordingly
+ stats.rating += mod;
+ stats.games += 1;
+ stats.played += 1;
+/* uint32 higher_rank = 0;
+ QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT (arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id);
+ if(result)
+ {
+ higher_rank = result->Fetch()->GetUInt32();
+ delete result;
+ }
+ stats.rank = higher_rank + 1;*/
+ // return the rating adjustment for display
+ return mod;
+}
+
+void ArenaTeam::MemberLost(Player * plr, uint32 againstrating)
+{
+ // called for each participant of a match after losing
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ if(itr->guid == plr->GetGUID())
+ {
+ // update personal rating
+ int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5);
+ float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f));
+ int32 mod = (int32)ceil(32.0f * (0.0f - chance));
+ personalrating += mod;
+ if(personalrating < 0)
+ personalrating = 0;
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating);
+ // update personal played stats
+ itr->played_week +=1;
+ itr->played_season +=1;
+ // update the unit fields
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->played_week);
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->played_season);
+ return;
+ }
+ }
+}
+
+void ArenaTeam::MemberWon(Player * plr, uint32 againstrating)
+{
+ // called for each participant after winning a match
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ if(itr->guid == plr->GetGUID())
+ {
+ // update personal rating
+ int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5);
+ float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f));
+ int32 mod = (int32)floor(32.0f * (1.0f - chance));
+ personalrating += mod;
+ if(personalrating < 0)
+ personalrating = 0;
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating);
+ // update personal stats
+ itr->played_week +=1;
+ itr->played_season +=1;
+ itr->wons_season += 1;
+ itr->wons_week += 1;
+ // update unit fields
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->played_week);
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->played_season);
+ return;
+ }
+ }
+}
+
+void ArenaTeam::UpdateArenaPointsHelper()
+{
+ // called after a match has ended and the stats are already modified
+ // helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
+ // 10 played games per week is a minimum
+ if(stats.games < 10)
+ return;
+ // to get points, a player has to participate in at least 30% of the matches
+ uint32 min_plays = (uint32)ceil(stats.games * 0.3);
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ // the player participated in enough games, update his points
+ if(itr->played_week >= min_plays)
+ {
+ // do it separately for online and offline players
+ // online players might have modified personal rating in MemberLost/MemberWon, that's not already saved to DB because of asynch queries
+ // offline player cant have a personal rating not matching the db
+ Player * plr = objmgr.GetPlayer(itr->guid);
+ uint32 points_to_add = 0;
+ if(plr)
+ points_to_add = GetPoints(plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5));
+ else
+ points_to_add = GetPoints(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5,itr->guid));
+ // it's enough to set the points in memory, the saving is done in separate function
+ CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid);
+ }
+ // the player failed to participate in enough games, so no points for him
+ else
+ {
+ CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", 0, Id, itr->guid);
+ }
+ }
+}
+
+void ArenaTeam::SaveToDB()
+{
+ // save team and member stats to db
+ // called after a match has ended
+ CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", stats.rating, stats.games, stats.played, stats.rank, stats.wins, stats.wins2, GetId());
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->played_week, itr->wons_week, itr->played_season, itr->wons_season, Id, itr->guid);
+ }
+}
+
+void ArenaTeam::FinishWeek()
+{
+ stats.games = 0; // played this week
+ stats.wins = 0; // wins this week
+ for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ itr->played_week = 0;
+ itr->wons_week = 0;
+ }
+}
+
+/*
+arenateam fields (id from 2.3.3 client):
+1414 - arena team id 2v2
+1415 - 0=captain, 1=member
+1416 - played this week
+1417 - played this season
+1418 - unk
+1419 - personal arena rating
+1420 - arena team id 3v3
+1421 - 0=captain, 1=member
+1422 - played this week
+1423 - played this season
+1424 - unk
+1425 - personal arena rating
+1426 - arena team id 5v5
+1427 - 0=captain, 1=member
+1428 - played this week
+1429 - played this season
+1430 - unk
+1431 - personal arena rating
+*/
diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp
index ca549f4d404..5526240528b 100644
--- a/src/game/AuctionHouse.cpp
+++ b/src/game/AuctionHouse.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "WorldPacket.h"
@@ -89,8 +89,8 @@ bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction)
sLog.outError("auction to item, that doesn't exist !!!!");
return false;
}
- data << auction->Id;
- data << pItem->GetUInt32Value(OBJECT_FIELD_ENTRY);
+ data << (uint32) auction->Id;
+ data << (uint32) pItem->GetEntry();
for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++)
{
@@ -245,7 +245,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
return;
}
- // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction)
+ // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction)
if(!it)
{
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND);
@@ -716,7 +716,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
ItemLocale const *il = objmgr.GetItemLocale(proto->ItemId);
if (il)
{
- if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
+ if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
name = il->Name[loc_idx];
}
}
diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp
index 4b8284c7c37..765d40f3962 100644
--- a/src/game/Bag.cpp
+++ b/src/game/Bag.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -41,7 +41,7 @@ Bag::~Bag()
{
for(int i = 0; i < MAX_BAG_SIZE; ++i)
if (m_bagslot[i])
- delete m_bagslot[i];
+ delete m_bagslot[i];
}
void Bag::AddToWorld()
@@ -71,7 +71,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
Object::_Create( guidlow, 0, HIGHGUID_CONTAINER );
- SetUInt32Value(OBJECT_FIELD_ENTRY, itemid);
+ SetEntry(itemid);
SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
@@ -85,7 +85,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
// Setting the number of Slots the Container has
SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots);
- // Cleanning 20 slots
+ // Cleaning 20 slots
for (uint8 i = 0; i < MAX_BAG_SIZE; i++)
{
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
@@ -213,6 +213,7 @@ uint8 Bag::GetSlotByItemGUID(uint64 guid) const
if(m_bagslot[i] != 0)
if(m_bagslot[i]->GetGUID() == guid)
return i;
+
return NULL_SLOT;
}
@@ -220,6 +221,6 @@ Item* Bag::GetItemByPos( uint8 slot ) const
{
if( slot < GetBagSize() )
return m_bagslot[slot];
-
+
return NULL;
}
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index bff970be3b7..862cfc638ca 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -63,16 +63,44 @@ ChatCommand * ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
+ static ChatCommand serverIdleRestartCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverIdleShutdownCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverRestartCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverShutdownCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
static ChatCommand serverCommandTable[] =
{
{ "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL },
{ "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", NULL },
- { "idlerestart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleRestartCommand, "", NULL },
- { "idleshutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleShutDownCommand, "", NULL },
+ { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable },
+ { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
{ "info", SEC_PLAYER, true, &ChatHandler::HandleServerInfoCommand, "", NULL },
{ "motd", SEC_PLAYER, true, &ChatHandler::HandleServerMotdCommand, "", NULL },
- { "restart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleRestartCommand, "", NULL },
- { "shutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleShutDownCommand, "", NULL },
+ { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
+ { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
{ "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 0ba253defd9..b62bae39d17 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -175,6 +175,7 @@ class ChatHandler
bool HandleModifyHonorCommand (const char* args);
bool HandleModifyRepCommand(const char* args);
bool HandleModifyArenaCommand(const char* args);
+ bool HandleModifyGenderCommand(const char* args);
bool HandleNpcAddCommand(const char* args);
bool HandleNpcAddMoveCommand(const char* args);
@@ -191,6 +192,7 @@ class ChatHandler
bool HandleNpcSetMoveTypeCommand(const char* args);
bool HandleNpcSpawnDistCommand(const char* args);
bool HandleNpcSpawnTimeCommand(const char* args);
+ bool HandleNpcTameCommand(const char* args);
bool HandleNpcTextEmoteCommand(const char* args);
bool HandleNpcUnFollowCommand(const char* args);
bool HandleNpcWhisperCommand(const char* args);
@@ -215,6 +217,7 @@ class ChatHandler
bool HandleReloadCommandCommand(const char* args);
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
+ bool HandleReloadDbScriptStringCommand(const char* args);
bool HandleReloadGameGraveyardZoneCommand(const char* args);
bool HandleReloadGameObjectScriptsCommand(const char* args);
bool HandleReloadGameTeleCommand(const char* args);
@@ -270,10 +273,15 @@ class ChatHandler
bool HandleServerCorpsesCommand(const char* args);
bool HandleServerExitCommand(const char* args);
+ bool HandleServerIdleRestartCommand(const char* args);
+ bool HandleServerIdleShutDownCommand(const char* args);
bool HandleServerInfoCommand(const char* args);
bool HandleServerMotdCommand(const char* args);
+ bool HandleServerRestartCommand(const char* args);
bool HandleServerSetMotdCommand(const char* args);
bool HandleServerSetLogLevelCommand(const char* args);
+ bool HandleServerShutDownCommand(const char* args);
+ bool HandleServerShutDownCancelCommand(const char* args);
bool HandleAddHonorCommand(const char* args);
bool HandleHonorAddKillCommand(const char* args);
@@ -327,11 +335,6 @@ class ChatHandler
bool HandleBanListAccountCommand(const char* args);
bool HandleBanListCharacterCommand(const char* args);
bool HandleBanListIPCommand(const char* args);
- bool HandleIdleRestartCommand(const char* args);
- bool HandleIdleShutDownCommand(const char* args);
- bool HandleShutDownCommand(const char* args);
- bool HandleRestartCommand(const char* args);
- bool HandleSecurityCommand(const char* args);
bool HandleGoXYCommand(const char* args);
bool HandleGoXYZCommand(const char* args);
bool HandleGoZoneXYCommand(const char* args);
@@ -365,7 +368,6 @@ class ChatHandler
bool HandleHideAreaCommand(const char* args);
bool HandleAddItemCommand(const char* args);
bool HandleAddItemSetCommand(const char* args);
- bool HandleModifyGenderCommand(const char* args);
bool HandlePetTpCommand(const char* args);
bool HandlePetUnlearnCommand(const char* args);
bool HandlePetLearnCommand(const char* args);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 5e3d3ac9f8e..8a58deb7f91 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -177,7 +177,7 @@ void Creature::RemoveCorpse()
float x,y,z,o;
GetRespawnCoord(x, y, z, &o);
- MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation(this,x,y,z,o);
+ GetMap()->CreatureRelocation(this,x,y,z,o);
}
/**
@@ -209,7 +209,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
}
}
- SetUInt32Value(OBJECT_FIELD_ENTRY, Entry); // normal entry always
+ SetEntry(Entry); // normal entry always
m_creatureInfo = cinfo; // map mode related always
// Cancel load if no model defined
@@ -352,7 +352,7 @@ void Creature::Update(uint32 diff)
lootForPickPocketed = false;
lootForBody = false;
- if(m_originalEntry != GetUInt32Value(OBJECT_FIELD_ENTRY))
+ if(m_originalEntry != GetEntry())
UpdateEntry(m_originalEntry);
CreatureInfo const *cinfo = GetCreatureInfo();
@@ -371,9 +371,9 @@ void Creature::Update(uint32 diff)
setDeathState( JUST_ALIVED );
//Call AI respawn virtual function
- AI()->JustRespawned();
+ i_AI->JustRespawned();
- MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
+ GetMap()->Add(this);
}
break;
}
@@ -435,7 +435,7 @@ void Creature::Update(uint32 diff)
{
// do not allow the AI to be changed during update
m_AI_locked = true;
- AI()->UpdateAI(diff);
+ i_AI->UpdateAI(diff);
m_AI_locked = false;
}
@@ -2096,9 +2096,14 @@ uint32 Creature::getLevelForTarget( Unit const* target ) const
return level;
}
-char const* Creature::GetScriptName() const
+std::string Creature::GetScriptName()
{
- return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptName;
+ return objmgr.GetScriptName(GetScriptId());
+}
+
+uint32 Creature::GetScriptId()
+{
+ return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptID;
}
VendorItemData const* Creature::GetVendorItems() const
diff --git a/src/game/Creature.h b/src/game/Creature.h
index be421f26ad2..d5b6b23a025 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_CREATURE_H
@@ -205,10 +205,11 @@ struct CreatureInfo
uint32 equipmentId;
uint32 MechanicImmuneMask;
uint32 flags_extra;
- char const* ScriptName;
+ uint32 ScriptID;
uint32 GetRandomValidModelId() const;
uint32 GetFirstValidModelId() const;
-
+
+ // helpers
SkillType GetRequiredLootSkill() const
{
if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT)
@@ -218,7 +219,7 @@ struct CreatureInfo
else
return SKILL_SKINNING; // normal case
}
-
+
bool isTameable() const
{
return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEBLE);
@@ -498,7 +499,9 @@ class TRINITY_DLL_SPEC Creature : public Unit
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
CreatureDataAddon const* GetCreatureAddon() const;
- char const* GetScriptName() const;
+
+ std::string GetScriptName();
+ uint32 GetScriptId();
void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 );
void sendPreparedGossip( Player* player );
@@ -524,7 +527,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const;
-
+
void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState
bool LoadFromDB(uint32 guid, Map *map);
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index 3cb8db202fa..ad663d13b38 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CreatureAI.h"
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h
index 877ed885152..76ba93a3cb5 100644
--- a/src/game/CreatureAIImpl.h
+++ b/src/game/CreatureAIImpl.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CREATUREAIIMPL_H
#define CREATUREAIIMPL_H
diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp
index 7219f71cd81..a4ee030c34e 100644
--- a/src/game/CreatureAIRegistry.cpp
+++ b/src/game/CreatureAIRegistry.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CreatureAIRegistry.h"
diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
index 2e0d297305c..5e15efafe6f 100644
--- a/src/game/CreatureAISelector.cpp
+++ b/src/game/CreatureAISelector.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Creature.h"
diff --git a/src/game/Formulas.h b/src/game/Formulas.h
index cef4fab9c7b..21c0b1f24fb 100644
--- a/src/game/Formulas.h
+++ b/src/game/Formulas.h
@@ -1,207 +1,208 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TRINITY_FORMULAS_H
-#define TRINITY_FORMULAS_H
-
-#include "World.h"
-
-namespace Trinity
-{
- namespace Honor
- {
- inline uint32 hk_honor_at_level(uint32 level, uint32 count=1)
- {
- return (uint32) ceil(count*(-0.53177f + 0.59357f * exp((level +23.54042f) / 26.07859f )));
- }
- }
- namespace XP
- {
- typedef enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
-
- inline uint32 GetGrayLevel(uint32 pl_level)
- {
- if( pl_level <= 5 )
- return 0;
- else if( pl_level <= 39 )
- return pl_level - 5 - pl_level/10;
- else if( pl_level <= 59 )
- return pl_level - 1 - pl_level/5;
- else
- return pl_level - 9;
- }
-
- inline XPColorChar GetColorCode(uint32 pl_level, uint32 mob_level)
- {
- if( mob_level >= pl_level + 5 )
- return RED;
- else if( mob_level >= pl_level + 3 )
- return ORANGE;
- else if( mob_level >= pl_level - 2 )
- return YELLOW;
- else if( mob_level > GetGrayLevel(pl_level) )
- return GREEN;
- else
- return GRAY;
- }
-
- inline uint32 GetZeroDifference(uint32 pl_level)
- {
- if( pl_level < 8 ) return 5;
- if( pl_level < 10 ) return 6;
- if( pl_level < 12 ) return 7;
- if( pl_level < 16 ) return 8;
- if( pl_level < 20 ) return 9;
- if( pl_level < 30 ) return 11;
- if( pl_level < 40 ) return 12;
- if( pl_level < 45 ) return 13;
- if( pl_level < 50 ) return 14;
- if( pl_level < 55 ) return 15;
- if( pl_level < 60 ) return 16;
- return 17;
- }
-
- inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content)
- {
- const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235;
- if( mob_level >= pl_level )
- {
- uint32 nLevelDiff = mob_level - pl_level;
- if (nLevelDiff > 4)
- nLevelDiff = 4;
- return ((pl_level*5 + nBaseExp) * (20 + nLevelDiff)/10 + 1)/2;
- }
- else
- {
- uint32 gray_level = GetGrayLevel(pl_level);
- if( mob_level > gray_level )
- {
- uint32 ZD = GetZeroDifference(pl_level);
- return (pl_level*5 + nBaseExp) * (ZD + mob_level - pl_level)/ZD;
- }
- return 0;
- }
- }
-
- inline uint32 Gain(Player *pl, Unit *u)
- {
- if(u->GetTypeId()==TYPEID_UNIT && (
- ((Creature*)u)->isTotem() || ((Creature*)u)->isPet() ||
- (((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) ))
- return 0;
-
- uint32 xp_gain= BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(pl->GetMapId(),pl->GetZoneId()));
- if( xp_gain == 0 )
- return 0;
-
- if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isElite())
- xp_gain *= 2;
-
- return (uint32)(xp_gain*sWorld.getRate(RATE_XP_KILL));
- }
-
- inline uint32 xp_Diff(uint32 lvl)
- {
- if( lvl < 29 )
- return 0;
- if( lvl == 29 )
- return 1;
- if( lvl == 30 )
- return 3;
- if( lvl == 31 )
- return 6;
- else
- return (5*(lvl-30));
- }
-
- inline uint32 mxp(uint32 lvl)
- {
- if (lvl < 60)
- {
- return (45 + (5*lvl));
- }
- else
- {
- return (235 + (5*lvl));
- }
- }
-
- inline uint32 xp_to_level(uint32 lvl)
- {
- uint32 xp = 0;
- if (lvl < 60)
- {
- xp = (8*lvl + xp_Diff(lvl)) * mxp(lvl);
- }
- else if (lvl == 60)
- {
- xp = (155 + mxp(lvl) * (1344 - 70 - ((69 - lvl) * (7 + (69 - lvl) * 8 - 1)/2)));
- }
- else if (lvl < 70)
- {
- xp = (155 + mxp(lvl) * (1344 - ((69-lvl) * (7 + (69 - lvl) * 8 - 1)/2)));
- }else
- {
- // level higher than 70 is not supported
- xp = (uint32)(779700 * (pow(sWorld.getRate(RATE_XP_PAST_70), (int32)lvl - 69)));
- return ((xp < 0x7fffffff) ? xp : 0x7fffffff);
- }
-
- // The XP to Level is always rounded to the nearest 100 points (50 rounded to high).
- xp = ((xp + 50) / 100) * 100; // use additional () for prevent free association operations in C++
-
- if ((lvl > 10) && (lvl < 60)) // compute discount added in 2.3.x
- {
- uint32 discount = (lvl < 28) ? (lvl - 10) : 18;
- xp = (xp * (100 - discount)) / 100; // apply discount
- xp = (xp / 100) * 100; // floor to hundreds
- }
-
- return xp;
- }
-
- inline float xp_in_group_rate(uint32 count, bool isRaid)
- {
- if(isRaid)
- {
- // FIX ME: must apply decrease modifiers dependent from raid size
- return 1.0f;
- }
- else
- {
- switch(count)
- {
- case 0:
- case 1:
- case 2:
- return 1.0f;
- case 3:
- return 1.166f;
- case 4:
- return 1.3f;
- case 5:
- default:
- return 1.4f;
- }
- }
- }
- }
-}
-#endif
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_FORMULAS_H
+#define TRINITY_FORMULAS_H
+
+#include "World.h"
+
+namespace Trinity
+{
+ namespace Honor
+ {
+ inline uint32 hk_honor_at_level(uint32 level, uint32 count=1)
+ {
+ return (uint32)ceil(count*(-0.53177f + 0.59357f * exp((level +23.54042f) / 26.07859f )));
+ }
+ }
+ namespace XP
+ {
+ typedef enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
+
+ inline uint32 GetGrayLevel(uint32 pl_level)
+ {
+ if( pl_level <= 5 )
+ return 0;
+ else if( pl_level <= 39 )
+ return pl_level - 5 - pl_level/10;
+ else if( pl_level <= 59 )
+ return pl_level - 1 - pl_level/5;
+ else
+ return pl_level - 9;
+ }
+
+ inline XPColorChar GetColorCode(uint32 pl_level, uint32 mob_level)
+ {
+ if( mob_level >= pl_level + 5 )
+ return RED;
+ else if( mob_level >= pl_level + 3 )
+ return ORANGE;
+ else if( mob_level >= pl_level - 2 )
+ return YELLOW;
+ else if( mob_level > GetGrayLevel(pl_level) )
+ return GREEN;
+ else
+ return GRAY;
+ }
+
+ inline uint32 GetZeroDifference(uint32 pl_level)
+ {
+ if( pl_level < 8 ) return 5;
+ if( pl_level < 10 ) return 6;
+ if( pl_level < 12 ) return 7;
+ if( pl_level < 16 ) return 8;
+ if( pl_level < 20 ) return 9;
+ if( pl_level < 30 ) return 11;
+ if( pl_level < 40 ) return 12;
+ if( pl_level < 45 ) return 13;
+ if( pl_level < 50 ) return 14;
+ if( pl_level < 55 ) return 15;
+ if( pl_level < 60 ) return 16;
+ return 17;
+ }
+
+ inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content)
+ {
+ //TODO: need modifier for CONTENT_71_80 different from CONTENT_61_70?
+ const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235;
+ if( mob_level >= pl_level )
+ {
+ uint32 nLevelDiff = mob_level - pl_level;
+ if (nLevelDiff > 4)
+ nLevelDiff = 4;
+ return ((pl_level*5 + nBaseExp) * (20 + nLevelDiff)/10 + 1)/2;
+ }
+ else
+ {
+ uint32 gray_level = GetGrayLevel(pl_level);
+ if( mob_level > gray_level )
+ {
+ uint32 ZD = GetZeroDifference(pl_level);
+ return (pl_level*5 + nBaseExp) * (ZD + mob_level - pl_level)/ZD;
+ }
+ return 0;
+ }
+ }
+
+ inline uint32 Gain(Player *pl, Unit *u)
+ {
+ if(u->GetTypeId()==TYPEID_UNIT && (
+ ((Creature*)u)->isTotem() || ((Creature*)u)->isPet() ||
+ (((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) ))
+ return 0;
+
+ uint32 xp_gain= BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(pl->GetMapId(),pl->GetZoneId()));
+ if( xp_gain == 0 )
+ return 0;
+
+ if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isElite())
+ xp_gain *= 2;
+
+ return (uint32)(xp_gain*sWorld.getRate(RATE_XP_KILL));
+ }
+
+ inline uint32 xp_Diff(uint32 lvl)
+ {
+ if( lvl < 29 )
+ return 0;
+ if( lvl == 29 )
+ return 1;
+ if( lvl == 30 )
+ return 3;
+ if( lvl == 31 )
+ return 6;
+ else
+ return (5*(lvl-30));
+ }
+
+ inline uint32 mxp(uint32 lvl)
+ {
+ if (lvl < 60)
+ {
+ return (45 + (5*lvl));
+ }
+ else
+ {
+ return (235 + (5*lvl));
+ }
+ }
+
+ inline uint32 xp_to_level(uint32 lvl)
+ {
+ uint32 xp = 0;
+ if (lvl < 60)
+ {
+ xp = (8*lvl + xp_Diff(lvl)) * mxp(lvl);
+ }
+ else if (lvl == 60)
+ {
+ xp = (155 + mxp(lvl) * (1344 - 70 - ((69 - lvl) * (7 + (69 - lvl) * 8 - 1)/2)));
+ }
+ else if (lvl < 70)
+ {
+ xp = (155 + mxp(lvl) * (1344 - ((69-lvl) * (7 + (69 - lvl) * 8 - 1)/2)));
+ }else
+ {
+ // level higher than 70 is not supported
+ xp = (uint32)(779700 * (pow(sWorld.getRate(RATE_XP_PAST_70), (int32)lvl - 69)));
+ return ((xp < 0x7fffffff) ? xp : 0x7fffffff);
+ }
+
+ // The XP to Level is always rounded to the nearest 100 points (50 rounded to high).
+ xp = ((xp + 50) / 100) * 100; // use additional () for prevent free association operations in C++
+
+ if ((lvl > 10) && (lvl < 60)) // compute discount added in 2.3.x
+ {
+ uint32 discount = (lvl < 28) ? (lvl - 10) : 18;
+ xp = (xp * (100 - discount)) / 100; // apply discount
+ xp = (xp / 100) * 100; // floor to hundreds
+ }
+
+ return xp;
+ }
+
+ inline float xp_in_group_rate(uint32 count, bool isRaid)
+ {
+ if(isRaid)
+ {
+ // FIX ME: must apply decrease modifiers dependent from raid size
+ return 1.0f;
+ }
+ else
+ {
+ switch(count)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return 1.0f;
+ case 3:
+ return 1.166f;
+ case 4:
+ return 1.3f;
+ case 5:
+ default:
+ return 1.4f;
+ }
+ }
+ }
+ }
+}
+#endif
diff --git a/src/game/GMTicketHandler.cpp b/src/game/GMTicketHandler.cpp
index 6d005c2806a..3a9651dc4fd 100644
--- a/src/game/GMTicketHandler.cpp
+++ b/src/game/GMTicketHandler.cpp
@@ -1,181 +1,177 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS
- *
- * Copyright (C) 2008 Trinity
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "Common.h"
-#include "Language.h"
-#include "WorldPacket.h"
-#include "Log.h"
-#include "GMTicketMgr.h"
-#include "ObjectAccessor.h"
-#include "Player.h"
-#include "Chat.h"
-
-void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
-{
- int len = text ? strlen(text) : 0;
- WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
- data << uint32(status); // standard 0x0A, 0x06 if text present
- if(status == 6)
- {
- data << text; // ticket text
- data << uint8(0x7); // ticket category
- data << float(0); // time from ticket creation?
- data << float(0); // const
- data << float(0); // const
- data << uint8(0); // const
- data << uint8(0); // const
- }
- SendPacket( &data );
-}
-
-void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
-{
- WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
- data << (uint32)time(NULL);
- data << (uint32)0;
- SendPacket( &data );
-
- GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow());
- if(ticket)
- SendGMTicketGetTicket(0x06,ticket->GetText());
- else
- SendGMTicketGetTicket(0x0A,0);
-}
-
-void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
-{
- CHECK_PACKET_SIZE(recv_data,1);
-
- std::string ticketText;
- recv_data >> ticketText;
-
- CharacterDatabase.escape_string(ticketText);
-
- if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
- ticket->SetText(ticketText.c_str());
- else
- sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
-}
-
-void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
-{
- ticketmgr.Delete(GetPlayer()->GetGUIDLow());
-
- WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
- data << uint32(9);
- SendPacket( &data );
-
- SendGMTicketGetTicket(0x0A, 0);
-}
-
-void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
-{
- CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
-
- uint32 map;
- float x, y, z;
- std::string ticketText = "";
- uint32 unk1, unk2;
-
- recv_data >> map >> x >> y >> z; // last check 2.4.3
- recv_data >> ticketText;
-
- // recheck
- CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
-
- recv_data >> unk1 >> unk2;
- // note: the packet might contain more data, but the exact structure of that is unknown
-
- sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
-
- CharacterDatabase.escape_string(ticketText);
-
- if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
- {
- WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
- data << uint32(1);
- SendPacket( &data );
- return;
- }
-
- ticketmgr.Create(_player->GetGUIDLow(), ticketText.c_str());
-
- WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
- data << (uint32)time(NULL);
- data << (uint32)0;
- SendPacket( &data );
-
- data.Initialize( SMSG_GMTICKET_CREATE, 4 );
- data << uint32(2);
- SendPacket( &data );
- DEBUG_LOG("update the ticket\n");
-
- //TODO: Guard player map
- HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
- for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
- {
- if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
- ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
- }
-}
-
-void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
-{
- WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
- data << uint32(1); // we can also disable ticket system by sending 0 value
-
- SendPacket( &data );
-}
-
-void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
-{
- // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
- CHECK_PACKET_SIZE(recv_data,4+4);
- uint32 x;
- recv_data >> x; // answer range? (6 = 0-5?)
- sLog.outDebug("SURVEY: X = %u", x);
-
- uint8 result[10];
- memset(result, 0, sizeof(result));
- for( int i = 0; i < 10; ++i)
- {
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
- uint32 questionID;
- recv_data >> questionID; // GMSurveyQuestions.dbc
- if (!questionID)
- break;
-
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
- uint8 value;
- std::string unk_text;
- recv_data >> value; // answer
- recv_data >> unk_text; // always empty?
-
- result[i] = value;
- sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
- }
-
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
- std::string comment;
- recv_data >> comment; // addional comment
- sLog.outDebug("SURVEY: comment %s", comment.c_str());
-
- // TODO: chart this data in some way
-}
+/*
+ * Copyright (C) 2005-2008 MaNGOS
+ *
+ * Copyright (C) 2008 Trinity
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Language.h"
+#include "WorldPacket.h"
+#include "Log.h"
+#include "GMTicketMgr.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "Chat.h"
+
+void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
+{
+ int len = text ? strlen(text) : 0;
+ WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
+ data << uint32(status); // standard 0x0A, 0x06 if text present
+ if(status == 6)
+ {
+ data << text; // ticket text
+ data << uint8(0x7); // ticket category
+ data << float(0); // time from ticket creation?
+ data << float(0); // const
+ data << float(0); // const
+ data << uint8(0); // const
+ data << uint8(0); // const
+ }
+ SendPacket( &data );
+}
+
+void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
+{
+ WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
+ data << (uint32)time(NULL);
+ data << (uint32)0;
+ SendPacket( &data );
+
+ GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow());
+ if(ticket)
+ SendGMTicketGetTicket(0x06,ticket->GetText());
+ else
+ SendGMTicketGetTicket(0x0A,0);
+}
+
+void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data,1);
+
+ std::string ticketText;
+ recv_data >> ticketText;
+
+ if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
+ ticket->SetText(ticketText.c_str());
+ else
+ sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
+}
+
+void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
+{
+ ticketmgr.Delete(GetPlayer()->GetGUIDLow());
+
+ WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
+ data << uint32(9);
+ SendPacket( &data );
+
+ SendGMTicketGetTicket(0x0A, 0);
+}
+
+void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
+
+ uint32 map;
+ float x, y, z;
+ std::string ticketText = "";
+ uint32 unk1, unk2;
+
+ recv_data >> map >> x >> y >> z; // last check 2.4.3
+ recv_data >> ticketText;
+
+ // recheck
+ CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
+
+ recv_data >> unk1 >> unk2;
+ // note: the packet might contain more data, but the exact structure of that is unknown
+
+ sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
+
+ if(ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
+ {
+ WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
+ data << uint32(1);
+ SendPacket( &data );
+ return;
+ }
+
+ ticketmgr.Create(_player->GetGUIDLow(), ticketText.c_str());
+
+ WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
+ data << (uint32)time(NULL);
+ data << (uint32)0;
+ SendPacket( &data );
+
+ data.Initialize( SMSG_GMTICKET_CREATE, 4 );
+ data << uint32(2);
+ SendPacket( &data );
+ DEBUG_LOG("update the ticket\n");
+
+ //TODO: Guard player map
+ HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
+ for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
+ ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
+ }
+}
+
+void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
+{
+ WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
+ data << uint32(1); // we can also disable ticket system by sending 0 value
+
+ SendPacket( &data );
+}
+
+void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
+{
+ // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
+ CHECK_PACKET_SIZE(recv_data,4+4);
+ uint32 x;
+ recv_data >> x; // answer range? (6 = 0-5?)
+ sLog.outDebug("SURVEY: X = %u", x);
+
+ uint8 result[10];
+ memset(result, 0, sizeof(result));
+ for( int i = 0; i < 10; ++i)
+ {
+ CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
+ uint32 questionID;
+ recv_data >> questionID; // GMSurveyQuestions.dbc
+ if (!questionID)
+ break;
+
+ CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
+ uint8 value;
+ std::string unk_text;
+ recv_data >> value; // answer
+ recv_data >> unk_text; // always empty?
+
+ result[i] = value;
+ sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
+ }
+
+ CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
+ std::string comment;
+ recv_data >> comment; // addional comment
+ sLog.outDebug("SURVEY: comment %s", comment.c_str());
+
+ // TODO: chart this data in some way
+}
diff --git a/src/game/GMTicketMgr.h b/src/game/GMTicketMgr.h
index a7b7a02ea17..a116f1806e2 100644
--- a/src/game/GMTicketMgr.h
+++ b/src/game/GMTicketMgr.h
@@ -1,118 +1,125 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _GMTICKETMGR_H
-#define _GMTICKETMGR_H
-
-#include "Policies/Singleton.h"
-#include "Database/DatabaseEnv.h"
-#include "Util.h"
-#include <map>
-
-class GMTicket
-{
- public:
- explicit GMTicket()
- {
- }
-
- GMTicket(uint32 guid, std::string text, time_t update) : m_guid(guid), m_text(text), m_lastUpdate(update)
- {
-
- }
-
- const char* GetText() const
- {
- return m_text.c_str();
- }
-
- uint64 GetLastUpdate() const
- {
- return m_lastUpdate;
- }
-
- void SetText(const char* text)
- {
- m_text = text ? text : "";
- m_lastUpdate = time(NULL);
- CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", m_text.c_str(), m_guid);
- }
-
- void DeleteFromDB() const
- {
- CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1", m_guid);
- }
-
- void SaveToDB() const
- {
- CharacterDatabase.BeginTransaction();
- DeleteFromDB();
- CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, GetText());
- CharacterDatabase.CommitTransaction();
- }
- private:
- uint32 m_guid;
- std::string m_text;
- time_t m_lastUpdate;
-};
-typedef std::map<uint32, GMTicket> GMTicketMap;
-
-class GMTicketMgr
-{
- public:
- GMTicketMgr() { }
- ~GMTicketMgr() { }
-
- void LoadGMTickets();
-
- GMTicket* GetGMTicket(uint32 guid)
- {
- GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
- if(itr == m_GMTicketMap.end())
- return NULL;
- return &(itr->second);
- }
-
- size_t GetTicketCount() const
- {
- return m_GMTicketMap.size();
- }
-
- void Delete(uint32 guid)
- {
- GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
- if(itr == m_GMTicketMap.end())
- return;
- itr->second.DeleteFromDB();
- m_GMTicketMap.erase(itr);
- }
-
- void DeleteAll();
-
- void Create(uint32 guid, const char* text)
- {
- GMTicket t = GMTicket(guid, text, time(NULL));
- t.SaveToDB();
- m_GMTicketMap[guid] = t;
- }
- private:
- GMTicketMap m_GMTicketMap;
-};
-
-#define ticketmgr Trinity::Singleton<GMTicketMgr>::Instance()
-#endif \ No newline at end of file
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _GMTICKETMGR_H
+#define _GMTICKETMGR_H
+
+#include "Policies/Singleton.h"
+#include "Database/DatabaseEnv.h"
+#include "Util.h"
+#include <map>
+
+class GMTicket
+{
+ public:
+ explicit GMTicket()
+ {
+ }
+
+ GMTicket(uint32 guid, std::string text, time_t update) : m_guid(guid), m_text(text), m_lastUpdate(update)
+ {
+
+ }
+
+ const char* GetText() const
+ {
+ return m_text.c_str();
+ }
+
+ uint64 GetLastUpdate() const
+ {
+ return m_lastUpdate;
+ }
+
+ void SetText(const char* text)
+ {
+ m_text = text ? text : "";
+ m_lastUpdate = time(NULL);
+
+ std::string escapedString = m_text;
+ CharacterDatabase.escape_string(escapedString);
+ CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", escapedString.c_str(), m_guid);
+ }
+
+ void DeleteFromDB() const
+ {
+ CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1", m_guid);
+ }
+
+ void SaveToDB() const
+ {
+ CharacterDatabase.BeginTransaction();
+ DeleteFromDB();
+
+ std::string escapedString = m_text;
+ CharacterDatabase.escape_string(escapedString);
+
+ CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, escapedString.c_str());
+ CharacterDatabase.CommitTransaction();
+ }
+ private:
+ uint32 m_guid;
+ std::string m_text;
+ time_t m_lastUpdate;
+};
+typedef std::map<uint32, GMTicket> GMTicketMap;
+
+class GMTicketMgr
+{
+ public:
+ GMTicketMgr() { }
+ ~GMTicketMgr() { }
+
+ void LoadGMTickets();
+
+ GMTicket* GetGMTicket(uint32 guid)
+ {
+ GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
+ if(itr == m_GMTicketMap.end())
+ return NULL;
+ return &(itr->second);
+ }
+
+ size_t GetTicketCount() const
+ {
+ return m_GMTicketMap.size();
+ }
+
+ void Delete(uint32 guid)
+ {
+ GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
+ if(itr == m_GMTicketMap.end())
+ return;
+ itr->second.DeleteFromDB();
+ m_GMTicketMap.erase(itr);
+ }
+
+ void DeleteAll();
+
+ void Create(uint32 guid, const char* text)
+ {
+ GMTicket t = GMTicket(guid, text, time(NULL));
+ t.SaveToDB();
+ m_GMTicketMap[guid] = t;
+ }
+ private:
+ GMTicketMap m_GMTicketMap;
+};
+
+#define ticketmgr Trinity::Singleton<GMTicketMgr>::Instance()
+#endif
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 7dc5a879913..afeaba98cc9 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_GAMEOBJECT_H
@@ -357,7 +357,7 @@ struct GameObjectInfo
uint32 data[24];
} raw;
};
- char *ScriptName;
+ uint32 ScriptId;
};
struct GameObjectLocale
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index 2c4ebfb0a3e..0c264a76d8b 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -179,7 +179,7 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt
case ITEM_SUBCLASS_CONTAINER:
return true;
case ITEM_SUBCLASS_SOUL_CONTAINER:
- if(!(pProto->BagFamily & BAG_FAMILY_MASK_SHARDS))
+ if(!(pProto->BagFamily & BAG_FAMILY_MASK_SOUL_SHARDS))
return false;
return true;
case ITEM_SUBCLASS_HERB_CONTAINER:
@@ -247,7 +247,7 @@ bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner)
{
Object::_Create( guidlow, 0, HIGHGUID_ITEM );
- SetUInt32Value(OBJECT_FIELD_ENTRY, itemid);
+ SetEntry(itemid);
SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
@@ -429,7 +429,7 @@ void Item::DeleteFromInventoryDB()
ItemPrototype const *Item::GetProto() const
{
- return objmgr.GetItemPrototype(GetUInt32Value(OBJECT_FIELD_ENTRY));
+ return objmgr.GetItemPrototype(GetEntry());
}
Player* Item::GetOwner()const
@@ -762,9 +762,7 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges)
{
// Better lost small time at check in comparison lost time at item save to DB.
- if( GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET)==id &&
- GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET)==duration &&
- GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET)==charges )
+ if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))
return;
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
@@ -775,7 +773,7 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint
void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration)
{
- if(GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET)==duration)
+ if(GetEnchantmentDuration(slot) == duration)
return;
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
@@ -784,17 +782,20 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration)
void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges)
{
+ if(GetEnchantmentCharges(slot) == charges)
+ return;
+
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
SetState(ITEM_CHANGED);
}
void Item::ClearEnchantment(EnchantmentSlot slot)
{
- if(!GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET))
+ if(!GetEnchantmentId(slot))
return;
- for(int x=0;x<3;x++)
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x,0);
+ for(uint8 x = 0; x < 3; ++x)
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
SetState(ITEM_CHANGED);
}
diff --git a/src/game/Item.h b/src/game/Item.h
index 7b265b9cbf2..72c09b0c1da 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_ITEM_H
@@ -228,7 +228,6 @@ class TRINITY_DLL_SPEC Item : public Object
bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const;
bool GemsFitSockets() const;
- uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); }
void SetCount(uint32 value) { SetUInt32Value (ITEM_FIELD_STACK_COUNT, value); }
uint32 GetMaxStackCount() const { return GetProto()->Stackable; }
diff --git a/src/game/ItemEnchantmentMgr.cpp b/src/game/ItemEnchantmentMgr.cpp
index 6d4197b0335..52a2e5dc1eb 100644
--- a/src/game/ItemEnchantmentMgr.cpp
+++ b/src/game/ItemEnchantmentMgr.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
diff --git a/src/game/ItemEnchantmentMgr.h b/src/game/ItemEnchantmentMgr.h
index a6b84c17418..97053c1ec36 100644
--- a/src/game/ItemEnchantmentMgr.h
+++ b/src/game/ItemEnchantmentMgr.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ITEM_ENCHANTMENT_MGR_H
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 5f9daa44336..c074ac98d77 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -313,9 +313,9 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
if (il)
{
- if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
+ if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
Name = il->Name[loc_idx];
- if (il->Description.size() > loc_idx && !il->Description[loc_idx].empty())
+ if (il->Description.size() > size_t(loc_idx) && !il->Description[loc_idx].empty())
Description = il->Description[loc_idx];
}
}
@@ -360,6 +360,8 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->Damage[i].DamageMax;
data << pProto->Damage[i].DamageType;
}
+
+ // resistances (7)
data << pProto->Armor;
data << pProto->HolyRes;
data << pProto->FireRes;
@@ -367,10 +369,11 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->FrostRes;
data << pProto->ShadowRes;
data << pProto->ArcaneRes;
+
data << pProto->Delay;
data << pProto->Ammo_type;
+ data << pProto->RangedModRange;
- data << (float)pProto->RangedModRange;
for(int s = 0; s < 5; s++)
{
// send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
@@ -976,7 +979,7 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data)
ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
if (il)
{
- if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
+ if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
Name = il->Name[loc_idx];
}
}
@@ -1027,7 +1030,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data)
return;
}
- if(item==gift) // not possible with pacjket from real client
+ if(item==gift) // not possable with pacjket from real client
{
_player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL );
return;
@@ -1072,16 +1075,16 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data)
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS));
- item->SetUInt32Value(OBJECT_FIELD_ENTRY, gift->GetUInt32Value(OBJECT_FIELD_ENTRY));
+ item->SetEntry(gift->GetEntry());
switch (item->GetEntry())
{
- case 5042: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 5043); break;
- case 5048: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 5044); break;
- case 17303: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 17302); break;
- case 17304: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 17305); break;
- case 17307: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 17308); break;
- case 21830: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 21831); break;
+ case 5042: item->SetEntry( 5043); break;
+ case 5048: item->SetEntry( 5044); break;
+ case 17303: item->SetEntry(17302); break;
+ case 17304: item->SetEntry(17305); break;
+ case 17307: item->SetEntry(17308); break;
+ case 21830: item->SetEntry(21831); break;
}
item->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, _player->GetGUID());
item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
index 4762bf1e26a..8a90ad49adb 100644
--- a/src/game/ItemPrototype.h
+++ b/src/game/ItemPrototype.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ITEMPROTOTYPE_H
@@ -99,16 +99,18 @@ enum ITEM_FLAGS
ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000,
ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000,
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
- ITEM_FLAGS_SPECIALUSE = 0x00800000 // last used flag in 2.3.0
+ ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0
+ ITEM_FLAGS_BOA = 0x08000000, // bind on account
+ ITEM_FLAGS_MILLABLE = 0x20000000
};
enum BAG_FAMILY_MASK
{
BAG_FAMILY_MASK_ARROWS = 0x00000001,
BAG_FAMILY_MASK_BULLETS = 0x00000002,
- BAG_FAMILY_MASK_SHARDS = 0x00000004,
+ BAG_FAMILY_MASK_SOUL_SHARDS = 0x00000004,
BAG_FAMILY_MASK_LEATHERWORKING_SUPP = 0x00000008,
- BAG_FAMILY_MASK_UNUSED = 0x00000010, // not used currently
+ BAG_FAMILY_MASK_INSCRIPTION_SUPP = 0x00000010,
BAG_FAMILY_MASK_HERBS = 0x00000020,
BAG_FAMILY_MASK_ENCHANTING_SUPP = 0x00000040,
BAG_FAMILY_MASK_ENGINEERING_SUPP = 0x00000080,
@@ -116,13 +118,11 @@ enum BAG_FAMILY_MASK
BAG_FAMILY_MASK_GEMS = 0x00000200,
BAG_FAMILY_MASK_MINING_SUPP = 0x00000400,
BAG_FAMILY_MASK_SOULBOUND_EQUIPMENT = 0x00000800,
- BAG_FAMILY_MASK_VANITY_PETS = 0x00001000
+ BAG_FAMILY_MASK_VANITY_PETS = 0x00001000,
+ BAG_FAMILY_MASK_CURRENCY_TOKENS = 0x00002000,
+ BAG_FAMILY_MASK_QUEST_ITEMS = 0x00004000
};
-/* TODO: Not entirely positive on need for this??
-enum SOCKET_CONTENT ();
-*/
-
enum SocketColor
{
SOCKET_COLOR_META = 1,
@@ -275,7 +275,7 @@ enum ItemSubclassArmor
ITEM_SUBCLASS_ARMOR_TOTEM = 9
};
-#define MAX_ITEM_SUBCLASS_ARMOR 10
+#define MAX_ITEM_SUBCLASS_ARMOR 10
enum ItemSubclassReagent
{
@@ -390,6 +390,22 @@ enum ItemSubclassJunk
#define MAX_ITEM_SUBCLASS_JUNK 6
+enum ItemSubclassGlyph
+{
+ ITEM_SUBCLASS_GLYPH_WARRIOR = 1,
+ ITEM_SUBCLASS_GLYPH_PALADIN = 2,
+ ITEM_SUBCLASS_GLYPH_HUNTER = 3,
+ ITEM_SUBCLASS_GLYPH_ROGUE = 4,
+ ITEM_SUBCLASS_GLYPH_PRIEST = 5,
+ ITEM_SUBCLASS_GLYPH_DEATH_KNIGHT = 6,
+ ITEM_SUBCLASS_GLYPH_SHAMAN = 7,
+ ITEM_SUBCLASS_GLYPH_MAGE = 8,
+ ITEM_SUBCLASS_GLYPH_WARLOCK = 9,
+ ITEM_SUBCLASS_GLYPH_DRUID = 11
+};
+
+#define MAX_ITEM_SUBCLASS_GLYPH 12
+
const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
{
MAX_ITEM_SUBCLASS_CONSUMABLE,
@@ -524,7 +540,7 @@ struct ItemPrototype
uint32 GemProperties; // id from GemProperties.dbc
uint32 RequiredDisenchantSkill;
float ArmorDamageModifier;
- char* ScriptName;
+ uint32 ScriptId;
uint32 DisenchantID;
uint32 FoodType;
uint32 MinMoneyLoot;
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 643a5b6f819..cd69e327042 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -1,4290 +1,4242 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "Common.h"
-#include "Database/DatabaseEnv.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
-#include "World.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-#include "Item.h"
-#include "GameObject.h"
-#include "Opcodes.h"
-#include "Chat.h"
-#include "ObjectAccessor.h"
-#include "MapManager.h"
-#include "Language.h"
-#include "World.h"
-#include "GameEvent.h"
-#include "SpellMgr.h"
-#include "AccountMgr.h"
-#include "GMTicketMgr.h"
-#include "WaypointManager.h"
-#include "Util.h"
-#include <cctype>
-#include <iostream>
-#include <fstream>
-#include <map>
-#include "GlobalEvents.h"
-
-#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
-
-static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
-{
- LANG_REP_HATED, LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL,
- LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED, LANG_REP_EXALTED
-};
-
-//mute player for some times
-bool ChatHandler::HandleMuteCommand(const char* args)
-{
- if (!*args)
- return false;
-
- char *charname = strtok((char*)args, " ");
- if (!charname)
- return false;
-
- std::string cname = charname;
-
- char *timetonotspeak = strtok(NULL, " ");
- if(!timetonotspeak)
- return false;
-
- uint32 notspeaktime = (uint32) atoi(timetonotspeak);
-
- if(!normalizePlayerName(cname))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
- if(!guid)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- Player *chr = objmgr.GetPlayer(guid);
-
- // check security
- uint32 account_id = 0;
- uint32 security = 0;
-
- if (chr)
- {
- account_id = chr->GetSession()->GetAccountId();
- security = chr->GetSession()->GetSecurity();
- }
- else
- {
- account_id = objmgr.GetPlayerAccountIdByGUID(guid);
- security = accmgr.GetSecurity(account_id);
- }
-
- if(m_session && security >= m_session->GetSecurity())
- {
- SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage(true);
- return false;
- }
-
- time_t mutetime = time(NULL) + notspeaktime*60;
-
- if (chr)
- chr->GetSession()->m_muteTime = mutetime;
-
- loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
-
- if(chr)
- ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
-
- PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
-
- return true;
-}
-
-//unmute player
-bool ChatHandler::HandleUnmuteCommand(const char* args)
-{
- if (!*args)
- return false;
-
- char *charname = strtok((char*)args, " ");
- if (!charname)
- return false;
-
- std::string cname = charname;
-
- if(!normalizePlayerName(cname))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
- if(!guid)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- Player *chr = objmgr.GetPlayer(guid);
-
- // check security
- uint32 account_id = 0;
- uint32 security = 0;
-
- if (chr)
- {
- account_id = chr->GetSession()->GetAccountId();
- security = chr->GetSession()->GetSecurity();
- }
- else
- {
- account_id = objmgr.GetPlayerAccountIdByGUID(guid);
- security = accmgr.GetSecurity(account_id);
- }
-
- if(m_session && security >= m_session->GetSecurity())
- {
- SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (chr)
- {
- if(chr->CanSpeak())
- {
- SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
- SetSentErrorMessage(true);
- return false;
- }
-
- chr->GetSession()->m_muteTime = 0;
- }
-
- loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
-
- if(chr)
- ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
-
- PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
- return true;
-}
-
-bool ChatHandler::HandleTargetObjectCommand(const char* args)
-{
- Player* pl = m_session->GetPlayer();
- QueryResult *result;
- GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
- if(*args)
- {
- int32 id = atoi((char*)args);
- if(id)
- result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1",
- pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
- else
- {
- std::string name = args;
- WorldDatabase.escape_string(name);
- result = WorldDatabase.PQuery(
- "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
- "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
- pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
- }
- }
- else
- {
- std::ostringstream eventFilter;
- eventFilter << " AND (event IS NULL ";
- bool initString = true;
-
- for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
- {
- if (initString)
- {
- eventFilter << "OR event IN (" <<*itr;
- initString =false;
- }
- else
- eventFilter << "," << *itr;
- }
-
- if (!initString)
- eventFilter << "))";
- else
- eventFilter << ")";
-
- result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
- "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
- "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
- m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
- }
-
- if (!result)
- {
- SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
- return true;
- }
-
- Field *fields = result->Fetch();
- uint32 lowguid = fields[0].GetUInt32();
- uint32 id = fields[1].GetUInt32();
- float x = fields[2].GetFloat();
- float y = fields[3].GetFloat();
- float z = fields[4].GetFloat();
- float o = fields[5].GetFloat();
- int mapid = fields[6].GetUInt16();
- delete result;
-
- GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
-
- if (!goI)
- {
- PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
- return false;
- }
-
- GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
-
- PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
-
- if(target)
- {
- int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
- if(curRespawnDelay < 0)
- curRespawnDelay = 0;
-
- std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
- std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
-
- PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
- }
- return true;
-}
-
-//teleport to gameobject
-bool ChatHandler::HandleGoObjectCommand(const char* args)
-{
- if(!*args)
- return false;
-
- Player* _player = m_session->GetPlayer();
-
- // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameobject");
- if(!cId)
- return false;
-
- int32 guid = atoi(cId);
- if(!guid)
- return false;
-
- float x, y, z, ort;
- int mapid;
-
- // by DB guid
- if (GameObjectData const* go_data = objmgr.GetGOData(guid))
- {
- x = go_data->posX;
- y = go_data->posY;
- z = go_data->posZ;
- ort = go_data->orientation;
- mapid = go_data->mapid;
- }
- else
- {
- SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
- {
- PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
- SetSentErrorMessage(true);
- return false;
- }
-
- // stop flight if need
- if(_player->isInFlight())
- {
- _player->GetMotionMaster()->MovementExpired();
- _player->m_taxi.ClearTaxiDestinations();
- }
- // save only in non-flight case
- else
- _player->SaveRecallPosition();
-
- _player->TeleportTo(mapid, x, y, z, ort);
- return true;
-}
-
-bool ChatHandler::HandleGoTriggerCommand(const char* args)
-{
- Player* _player = m_session->GetPlayer();
-
- if (!*args)
- return false;
-
- char *atId = strtok((char*)args, " ");
- if (!atId)
- return false;
-
- int32 i_atId = atoi(atId);
-
- if(!i_atId)
- return false;
-
- AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
- if (!at)
- {
- PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
- {
- PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
- SetSentErrorMessage(true);
- return false;
- }
-
- // stop flight if need
- if(_player->isInFlight())
- {
- _player->GetMotionMaster()->MovementExpired();
- _player->m_taxi.ClearTaxiDestinations();
- }
- // save only in non-flight case
- else
- _player->SaveRecallPosition();
-
- _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
- return true;
-}
-
-bool ChatHandler::HandleGoGraveyardCommand(const char* args)
-{
- Player* _player = m_session->GetPlayer();
-
- if (!*args)
- return false;
-
- char *gyId = strtok((char*)args, " ");
- if (!gyId)
- return false;
-
- int32 i_gyId = atoi(gyId);
-
- if(!i_gyId)
- return false;
-
- WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
- if (!gy)
- {
- PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
- {
- PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- // stop flight if need
- if(_player->isInFlight())
- {
- _player->GetMotionMaster()->MovementExpired();
- _player->m_taxi.ClearTaxiDestinations();
- }
- // save only in non-flight case
- else
- _player->SaveRecallPosition();
-
- _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
- return true;
-}
-
-/** \brief Teleport the GM to the specified creature
- *
- * .gocreature <GUID> --> TP using creature.guid
- * .gocreature azuregos --> TP player to the mob with this name
- * Warning: If there is more than one mob with this name
- * you will be teleported to the first one that is found.
- * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
- * Warning: If there is more than one mob with this "id"
- * you will be teleported to the first one that is found.
- */
-//teleport to creature
-bool ChatHandler::HandleGoCreatureCommand(const char* args)
-{
- if(!*args)
- return false;
- Player* _player = m_session->GetPlayer();
-
- // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
- char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
- if (!pParam1)
- return false;
-
- std::ostringstream whereClause;
-
- // User wants to teleport to the NPC's template entry
- if( strcmp(pParam1, "id") == 0 )
- {
- //sLog.outError("DEBUG: ID found");
-
- // Get the "creature_template.entry"
- // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
- char* tail = strtok(NULL,"");
- if(!tail)
- return false;
- char* cId = extractKeyFromLink(tail,"Hcreature_entry");
- if(!cId)
- return false;
-
- int32 tEntry = atoi(cId);
- //sLog.outError("DEBUG: ID value: %d", tEntry);
- if(!tEntry)
- return false;
-
- whereClause << "WHERE id = '" << tEntry << "'";
- }
- else
- {
- //sLog.outError("DEBUG: ID *not found*");
-
- int32 guid = atoi(pParam1);
-
- // Number is invalid - maybe the user specified the mob's name
- if(!guid)
- {
- std::string name = pParam1;
- WorldDatabase.escape_string(name);
- whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
- }
- else
- {
- whereClause << "WHERE guid = '" << guid << "'";
- }
- }
- //sLog.outError("DEBUG: %s", whereClause.c_str());
-
- QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
- if (!result)
- {
- SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
- SetSentErrorMessage(true);
- return false;
- }
- if( result->GetRowCount() > 1 )
- {
- SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
- }
-
- Field *fields = result->Fetch();
- float x = fields[0].GetFloat();
- float y = fields[1].GetFloat();
- float z = fields[2].GetFloat();
- float ort = fields[3].GetFloat();
- int mapid = fields[4].GetUInt16();
-
- delete result;
-
- if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
- {
- PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
- SetSentErrorMessage(true);
- return false;
- }
-
- // stop flight if need
- if(_player->isInFlight())
- {
- _player->GetMotionMaster()->MovementExpired();
- _player->m_taxi.ClearTaxiDestinations();
- }
- // save only in non-flight case
- else
- _player->SaveRecallPosition();
-
- _player->TeleportTo(mapid, x, y, z, ort);
- return true;
-}
-
-bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
-{
- uint64 guid = m_session->GetPlayer()->GetSelection();
-
- if (guid == 0)
- {
- SendSysMessage(LANG_NO_SELECTION);
- SetSentErrorMessage(true);
- return false;
- }
-
- PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
- return true;
-}
-
-bool ChatHandler::HandleLookupFactionCommand(const char* args)
-{
- if (!*args)
- return false;
-
- // Can be NULL at console call
- Player *target = getSelectedPlayer ();
-
- std::string namepart = args;
- std::wstring wnamepart;
-
- if (!Utf8toWStr (namepart,wnamepart))
- return false;
-
- // converting string that we try to find to lower case
- wstrToLower (wnamepart);
-
- uint32 counter = 0; // Counter for figure out that we found smth.
-
- for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
- {
- FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
- if (factionEntry)
- {
- FactionState const* repState = NULL;
- if(target)
- {
- FactionStateList::const_iterator repItr = target->m_factions.find (factionEntry->reputationListID);
- if(repItr != target->m_factions.end())
- repState = &repItr->second;
- }
-
- int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
- std::string name = factionEntry->name[loc];
- if(name.empty())
- continue;
-
- if (!Utf8FitTo(name, wnamepart))
- {
- loc = 0;
- for(; loc < MAX_LOCALE; ++loc)
- {
- if(m_session && loc==m_session->GetSessionDbcLocale())
- continue;
-
- name = factionEntry->name[loc];
- if(name.empty())
- continue;
-
- if (Utf8FitTo(name, wnamepart))
- break;
- }
- }
-
- if(loc < MAX_LOCALE)
- {
- // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
- // or "id - [faction] [no reputation]" format
- std::ostringstream ss;
- if (m_session)
- ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
- else
- ss << id << " - " << name << " " << localeNames[loc];
-
- if (repState) // and then target!=NULL also
- {
- ReputationRank rank = target->GetReputationRank(factionEntry);
- std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
-
- ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
-
- if(repState->Flags & FACTION_FLAG_VISIBLE)
- ss << GetTrinityString(LANG_FACTION_VISIBLE);
- if(repState->Flags & FACTION_FLAG_AT_WAR)
- ss << GetTrinityString(LANG_FACTION_ATWAR);
- if(repState->Flags & FACTION_FLAG_PEACE_FORCED)
- ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
- if(repState->Flags & FACTION_FLAG_HIDDEN)
- ss << GetTrinityString(LANG_FACTION_HIDDEN);
- if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
- ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
- if(repState->Flags & FACTION_FLAG_INACTIVE)
- ss << GetTrinityString(LANG_FACTION_INACTIVE);
- }
- else
- ss << GetTrinityString(LANG_FACTION_NOREPUTATION);
-
- SendSysMessage(ss.str().c_str());
- counter++;
- }
- }
- }
-
- if (counter == 0) // if counter == 0 then we found nth
- SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
- return true;
-}
-
-bool ChatHandler::HandleModifyRepCommand(const char * args)
-{
- if (!*args) return false;
-
- Player* target = NULL;
- target = getSelectedPlayer();
-
- if(!target)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
- if(!factionTxt)
- return false;
-
- uint32 factionId = atoi(factionTxt);
-
- int32 amount = 0;
- char *rankTxt = strtok(NULL, " ");
- if (!factionTxt || !rankTxt)
- return false;
-
- amount = atoi(rankTxt);
- if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
- {
- std::string rankStr = rankTxt;
- std::wstring wrankStr;
- if(!Utf8toWStr(rankStr,wrankStr))
- return false;
- wstrToLower( wrankStr );
-
- int r = 0;
- amount = -42000;
- for (; r < MAX_REPUTATION_RANK; ++r)
- {
- std::string rank = GetTrinityString(ReputationRankStrIndex[r]);
- if(rank.empty())
- continue;
-
- std::wstring wrank;
- if(!Utf8toWStr(rank,wrank))
- continue;
-
- wstrToLower(wrank);
-
- if(wrank.substr(0,wrankStr.size())==wrankStr)
- {
- char *deltaTxt = strtok(NULL, " ");
- if (deltaTxt)
- {
- int32 delta = atoi(deltaTxt);
- if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1))
- {
- PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1));
- SetSentErrorMessage(true);
- return false;
- }
- amount += delta;
- }
- break;
- }
- amount += Player::ReputationRank_Length[r];
- }
- if (r >= MAX_REPUTATION_RANK)
- {
- PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
- SetSentErrorMessage(true);
- return false;
- }
- }
-
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
-
- if (!factionEntry)
- {
- PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (factionEntry->reputationListID < 0)
- {
- PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
- SetSentErrorMessage(true);
- return false;
- }
-
- target->SetFactionReputation(factionEntry,amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
- return true;
-}
-
-bool ChatHandler::HandleNameCommand(const char* args)
-{
- /* Temp. disabled
- if(!*args)
- return false;
-
- if(strlen((char*)args)>75)
- {
- PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
- return true;
- }
-
- for (uint8 i = 0; i < strlen(args); i++)
- {
- if(!isalpha(args[i]) && args[i]!=' ')
- {
- SendSysMessage(LANG_CHARS_ONLY);
- return false;
- }
- }
-
- uint64 guid;
- guid = m_session->GetPlayer()->GetSelection();
- if (guid == 0)
- {
- SendSysMessage(LANG_NO_SELECTION);
- return true;
- }
-
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
-
- if(!pCreature)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- return true;
- }
-
- pCreature->SetName(args);
- uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
- pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
-
- pCreature->SaveToDB();
- */
-
- return true;
-}
-
-bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
-{
- /* Temp. disabled
-
- if(!*args)
- args = "";
-
- if(strlen((char*)args)>75)
- {
-
- PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
- return true;
- }
-
- for (uint8 i = 0; i < strlen(args); i++)
- {
- if(!isalpha(args[i]) && args[i]!=' ')
- {
- SendSysMessage(LANG_CHARS_ONLY);
- return false;
- }
- }
- uint64 guid;
- guid = m_session->GetPlayer()->GetSelection();
- if (guid == 0)
- {
- SendSysMessage(LANG_NO_SELECTION);
- return true;
- }
-
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
-
- if(!pCreature)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- return true;
- }
-
- uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
- pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
-
- pCreature->SaveToDB();
- */
- return true;
-}
-
-//move item to other slot
-bool ChatHandler::HandleItemMoveCommand(const char* args)
-{
- if(!*args)
- return false;
- uint8 srcslot, dstslot;
-
- char* pParam1 = strtok((char*)args, " ");
- if (!pParam1)
- return false;
-
- char* pParam2 = strtok(NULL, " ");
- if (!pParam2)
- return false;
-
- srcslot = (uint8)atoi(pParam1);
- dstslot = (uint8)atoi(pParam2);
-
- if(srcslot==dstslot)
- return true;
-
- if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
- return false;
-
- if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
- return false;
-
- uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
- uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
-
- m_session->GetPlayer()->SwapItem( src, dst );
-
- return true;
-}
-
-//add spawn of creature
-bool ChatHandler::HandleNpcAddCommand(const char* args)
-{
- if(!*args)
- return false;
- char* charID = strtok((char*)args, " ");
- if (!charID)
- return false;
-
- char* team = strtok(NULL, " ");
- int32 teamval = 0;
- if (team) { teamval = atoi(team); }
- if (teamval < 0) { teamval = 0; }
-
- uint32 id = atoi(charID);
-
- Player *chr = m_session->GetPlayer();
- float x = chr->GetPositionX();
- float y = chr->GetPositionY();
- float z = chr->GetPositionZ();
- float o = chr->GetOrientation();
- Map *map = chr->GetMap();
-
- Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
- {
- delete pCreature;
- return false;
- }
-
- pCreature->Relocate(x,y,z,o);
-
- if(!pCreature->IsPositionValid())
- {
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
- delete pCreature;
- return false;
- }
-
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
-
- uint32 db_guid = pCreature->GetDBTableGUIDLow();
-
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- pCreature->LoadFromDB(db_guid, map);
-
- map->Add(pCreature);
- objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
- return true;
-}
-
-bool ChatHandler::HandleNpcDeleteCommand(const char* args)
-{
- Creature* unit = NULL;
-
- if(*args)
- {
- // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hcreature");
- if(!cId)
- return false;
-
- uint32 lowguid = atoi(cId);
- if(!lowguid)
- return false;
-
- if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
- unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
- }
- else
- unit = getSelectedCreature();
-
- if(!unit || unit->isPet() || unit->isTotem())
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- // Delete the creature
- unit->CombatStop();
- unit->DeleteFromDB();
- unit->CleanupsBeforeDelete();
- unit->AddObjectToRemoveList();
-
- SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
-
- return true;
-}
-
-//delete object by selection or guid
-bool ChatHandler::HandleDelObjectCommand(const char* args)
-{
- // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameobject");
- if(!cId)
- return false;
-
- uint32 lowguid = atoi(cId);
- if(!lowguid)
- return false;
-
- GameObject* obj = NULL;
-
- // by DB guid
- if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
- obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
-
- if(!obj)
- {
- PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 owner_guid = obj->GetOwnerGUID();
- if(owner_guid)
- {
- Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
- if(!owner && !IS_PLAYER_GUID(owner_guid))
- {
- PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
- SetSentErrorMessage(true);
- return false;
- }
-
- owner->RemoveGameObject(obj,false);
- }
-
- obj->SetRespawnTime(0); // not save respawn time
- obj->Delete();
- obj->DeleteFromDB();
-
- PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
-
- return true;
-}
-
-//turn selected object
-bool ChatHandler::HandleTurnObjectCommand(const char* args)
-{
- // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameobject");
- if(!cId)
- return false;
-
- uint32 lowguid = atoi(cId);
- if(!lowguid)
- return false;
-
- GameObject* obj = NULL;
-
- // by DB guid
- if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
- obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
-
- if(!obj)
- {
- PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* po = strtok(NULL, " ");
- float o;
-
- if (po)
- {
- o = (float)atof(po);
- }
- else
- {
- Player *chr = m_session->GetPlayer();
- o = chr->GetOrientation();
- }
-
- float rot2 = sin(o/2);
- float rot3 = cos(o/2);
-
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
- map->Remove(obj,false);
-
- obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
-
- obj->SetFloatValue(GAMEOBJECT_FACING, o);
- obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
- obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
-
- map->Add(obj);
-
- obj->SaveToDB();
- obj->Refresh();
-
- PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o);
-
- return true;
-}
-
-//move selected creature
-bool ChatHandler::HandleNpcMoveCommand(const char* args)
-{
- uint32 lowguid = 0;
-
- Creature* pCreature = getSelectedCreature();
-
- if(!pCreature)
- {
- // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hcreature");
- if(!cId)
- return false;
-
- uint32 lowguid = atoi(cId);
-
- /* FIXME: impossibel without entry
- if(lowguid)
- pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
- */
-
- // Attempting creature load from DB data
- if(!pCreature)
- {
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 map_id = data->mapid;
-
- if(m_session->GetPlayer()->GetMapId()!=map_id)
- {
- PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- lowguid = pCreature->GetDBTableGUIDLow();
- }
- }
- else
- {
- lowguid = pCreature->GetDBTableGUIDLow();
- }
-
- float x = m_session->GetPlayer()->GetPositionX();
- float y = m_session->GetPlayer()->GetPositionY();
- float z = m_session->GetPlayer()->GetPositionZ();
- float o = m_session->GetPlayer()->GetOrientation();
-
- if (pCreature)
- {
- if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
- {
- const_cast<CreatureData*>(data)->posX = x;
- const_cast<CreatureData*>(data)->posY = y;
- const_cast<CreatureData*>(data)->posZ = z;
- const_cast<CreatureData*>(data)->orientation = o;
- }
- MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
- pCreature->GetMotionMaster()->Initialize();
- if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- pCreature->setDeathState(JUST_DIED);
- pCreature->Respawn();
- }
- }
-
- WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
- PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
- return true;
-}
-
-//move selected object
-bool ChatHandler::HandleMoveObjectCommand(const char* args)
-{
- // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameobject");
- if(!cId)
- return false;
-
- uint32 lowguid = atoi(cId);
- if(!lowguid)
- return false;
-
- GameObject* obj = NULL;
-
- // by DB guid
- if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
- obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
-
- if(!obj)
- {
- PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* px = strtok(NULL, " ");
- char* py = strtok(NULL, " ");
- char* pz = strtok(NULL, " ");
-
- if (!px)
- {
- Player *chr = m_session->GetPlayer();
-
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
- map->Remove(obj,false);
-
- obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
- obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
- obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
- obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
-
- map->Add(obj);
- }
- else
- {
- if(!py || !pz)
- return false;
-
- float x = (float)atof(px);
- float y = (float)atof(py);
- float z = (float)atof(pz);
-
- if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
- {
- PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
- SetSentErrorMessage(true);
- return false;
- }
-
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
- map->Remove(obj,false);
-
- obj->Relocate(x, y, z, obj->GetOrientation());
- obj->SetFloatValue(GAMEOBJECT_POS_X, x);
- obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
- obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
-
- map->Add(obj);
- }
-
- obj->SaveToDB();
- obj->Refresh();
-
- PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
-
- return true;
-}
-
-//demorph player or unit
-bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
-{
- Unit *target = getSelectedUnit();
- if(!target)
- target = m_session->GetPlayer();
-
- target->DeMorph();
-
- return true;
-}
-
-//add item in vendorlist
-bool ChatHandler::HandleAddVendorItemCommand(const char* args)
-{
- if (!*args)
- return false;
-
- char* pitem = extractKeyFromLink((char*)args,"Hitem");
- if (!pitem)
- {
- SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 itemId = atol(pitem);
-
- char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
- uint32 maxcount = 0;
- if (fmaxcount)
- maxcount = atol(fmaxcount);
-
- char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
- uint32 incrtime = 0;
- if (fincrtime)
- incrtime = atol(fincrtime);
-
- char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
- uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
-
- Creature* vendor = getSelectedCreature();
-
- uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
-
- if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
- {
- SetSentErrorMessage(true);
- return false;
- }
-
- objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
-
- ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
-
- PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
- return true;
-}
-
-//del item from vendor list
-bool ChatHandler::HandleDelVendorItemCommand(const char* args)
-{
- if (!*args)
- return false;
-
- Creature* vendor = getSelectedCreature();
- if (!vendor || !vendor->isVendor())
- {
- SendSysMessage(LANG_COMMAND_VENDORSELECTION);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* pitem = extractKeyFromLink((char*)args,"Hitem");
- if (!pitem)
- {
- SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
- SetSentErrorMessage(true);
- return false;
- }
- uint32 itemId = atol(pitem);
-
-
- if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
- {
- PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
- SetSentErrorMessage(true);
- return false;
- }
-
- ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
-
- PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
- return true;
-}
-
-//add move for creature
-bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
-{
- if(!*args)
- return false;
-
- char* guid_str = strtok((char*)args, " ");
- char* wait_str = strtok((char*)NULL, " ");
-
- uint32 lowguid = atoi((char*)guid_str);
-
- Creature* pCreature = NULL;
-
- /* FIXME: impossible without entry
- if(lowguid)
- pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
- */
-
- // attempt check creature existence by DB data
- if(!pCreature)
- {
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- // obtain real GUID for DB operations
- lowguid = pCreature->GetDBTableGUIDLow();
- }
-
- int wait = wait_str ? atoi(wait_str) : 0;
-
- if(wait < 0)
- wait = 0;
-
- Player* player = m_session->GetPlayer();
-
- WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
-
- // update movement type
- WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
- if(pCreature)
- {
- pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- pCreature->GetMotionMaster()->Initialize();
- if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- pCreature->setDeathState(JUST_DIED);
- pCreature->Respawn();
- }
- pCreature->SaveToDB();
- }
-
- SendSysMessage(LANG_WAYPOINT_ADDED);
-
- return true;
-}
-
-/**
- * Set the movement type for an NPC.<br/>
- * <br/>
- * Valid movement types are:
- * <ul>
- * <li> stay - NPC wont move </li>
- * <li> random - NPC will move randomly according to the spawndist </li>
- * <li> way - NPC will move with given waypoints set </li>
- * </ul>
- * additional parameter: NODEL - so no waypoints are deleted, if you
- * change the movement type
- */
-bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
-{
- if(!*args)
- return false;
-
- // 3 arguments:
- // GUID (optional - you can also select the creature)
- // stay|random|way (determines the kind of movement)
- // NODEL (optional - tells the system NOT to delete any waypoints)
- // this is very handy if you want to do waypoints, that are
- // later switched on/off according to special events (like escort
- // quests, etc)
- char* guid_str = strtok((char*)args, " ");
- char* type_str = strtok((char*)NULL, " ");
- char* dontdel_str = strtok((char*)NULL, " ");
-
- bool doNotDelete = false;
-
- if(!guid_str)
- return false;
-
- uint32 lowguid = 0;
- Creature* pCreature = NULL;
-
- if( dontdel_str )
- {
- //sLog.outError("DEBUG: All 3 params are set");
-
- // All 3 params are set
- // GUID
- // type
- // doNotDEL
- if( stricmp( dontdel_str, "NODEL" ) == 0 )
- {
- //sLog.outError("DEBUG: doNotDelete = true;");
- doNotDelete = true;
- }
- }
- else
- {
- // Only 2 params - but maybe NODEL is set
- if( type_str )
- {
- sLog.outError("DEBUG: Only 2 params ");
- if( stricmp( type_str, "NODEL" ) == 0 )
- {
- //sLog.outError("DEBUG: type_str, NODEL ");
- doNotDelete = true;
- type_str = NULL;
- }
- }
- }
-
- if(!type_str) // case .setmovetype $move_type (with selected creature)
- {
- type_str = guid_str;
- pCreature = getSelectedCreature();
- if(!pCreature || pCreature->isPet())
- return false;
- lowguid = pCreature->GetDBTableGUIDLow();
- }
- else // case .setmovetype #creature_guid $move_type (with selected creature)
- {
- lowguid = atoi((char*)guid_str);
-
- /* impossible without entry
- if(lowguid)
- pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
- */
-
- // attempt check creature existence by DB data
- if(!pCreature)
- {
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- lowguid = pCreature->GetDBTableGUIDLow();
- }
- }
-
- // now lowguid is low guid really existed creature
- // and pCreature point (maybe) to this creature or NULL
-
- MovementGeneratorType move_type;
-
- std::string type = type_str;
-
- if(type == "stay")
- move_type = IDLE_MOTION_TYPE;
- else if(type == "random")
- move_type = RANDOM_MOTION_TYPE;
- else if(type == "way")
- move_type = WAYPOINT_MOTION_TYPE;
- else
- return false;
-
- // update movement type
- if(doNotDelete == false)
- WaypointMgr.DeletePath(lowguid);
-
- if(pCreature)
- {
- pCreature->SetDefaultMovementType(move_type);
- pCreature->GetMotionMaster()->Initialize();
- if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- pCreature->setDeathState(JUST_DIED);
- pCreature->Respawn();
- }
- pCreature->SaveToDB();
- }
- if( doNotDelete == false )
- {
- PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
- }
- else
- {
- PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
- }
-
- return true;
-} // HandleNpcSetMoveTypeCommand
-
-//change level of creature or pet
-bool ChatHandler::HandleChangeLevelCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint8 lvl = (uint8) atoi((char*)args);
- if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
- {
- SendSysMessage(LANG_BAD_VALUE);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature* pCreature = getSelectedCreature();
- if(!pCreature)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(pCreature->isPet())
- {
- ((Pet*)pCreature)->GivePetLevel(lvl);
- }
- else
- {
- pCreature->SetMaxHealth( 100 + 30*lvl);
- pCreature->SetHealth( 100 + 30*lvl);
- pCreature->SetLevel( lvl);
- pCreature->SaveToDB();
- }
-
- return true;
-}
-
-//set npcflag of creature
-bool ChatHandler::HandleNpcFlagCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint32 npcFlags = (uint32) atoi((char*)args);
-
- Creature* pCreature = getSelectedCreature();
-
- if(!pCreature)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
-
- WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
-
- SendSysMessage(LANG_VALUE_SAVED_REJOIN);
-
- return true;
-}
-
-//set model of creature
-bool ChatHandler::HandleNpcSetModelCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint32 displayId = (uint32) atoi((char*)args);
-
- Creature *pCreature = getSelectedCreature();
-
- if(!pCreature || pCreature->isPet())
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- pCreature->SetDisplayId(displayId);
- pCreature->SetNativeDisplayId(displayId);
-
- pCreature->SaveToDB();
-
- return true;
-}
-
-//morph creature or player
-bool ChatHandler::HandleMorphCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint16 display_id = (uint16)atoi((char*)args);
-
- Unit *target = getSelectedUnit();
- if(!target)
- target = m_session->GetPlayer();
-
- target->SetDisplayId(display_id);
-
- return true;
-}
-
-//set faction of creature
-bool ChatHandler::HandleNpcFactionIdCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint32 factionId = (uint32) atoi((char*)args);
-
- if (!sFactionTemplateStore.LookupEntry(factionId))
- {
- PSendSysMessage(LANG_WRONG_FACTION, factionId);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature* pCreature = getSelectedCreature();
-
- if(!pCreature)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- pCreature->setFaction(factionId);
-
- // faction is set in creature_template - not inside creature
-
- // update in memory
- if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
- {
- const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
- const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
- }
-
- // and DB
- WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
-
- return true;
-}
-
-//kick player
-bool ChatHandler::HandleKickPlayerCommand(const char *args)
-{
- char* kickName = strtok((char*)args, " ");
- if (!kickName)
- {
- Player* player = getSelectedPlayer();
-
- if(!player)
- {
- SendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(player==m_session->GetPlayer())
- {
- SendSysMessage(LANG_COMMAND_KICKSELF);
- SetSentErrorMessage(true);
- return false;
- }
-
- player->GetSession()->KickPlayer();
- }
- else
- {
- std::string name = kickName;
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(m_session && name==m_session->GetPlayer()->GetName())
- {
- SendSysMessage(LANG_COMMAND_KICKSELF);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(sWorld.KickPlayer(name))
- {
- PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
- }
- else
- PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
- }
-
- return true;
-}
-
-//show info of player
-bool ChatHandler::HandlePInfoCommand(const char* args)
-{
- Player* target = NULL;
- uint64 targetGUID = 0;
-
- char* px = strtok((char*)args, " ");
- char* py = NULL;
-
- std::string name;
-
- if (px)
- {
- name = px;
-
- if(name.empty())
- return false;
-
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- target = objmgr.GetPlayer(name.c_str());
- if (target)
- py = strtok(NULL, " ");
- else
- {
- targetGUID = objmgr.GetPlayerGUIDByName(name);
- if(targetGUID)
- py = strtok(NULL, " ");
- else
- py = px;
- }
- }
-
- if(!target && !targetGUID)
- {
- target = getSelectedPlayer();
- }
-
- if(!target && !targetGUID)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 accId = 0;
- uint32 money = 0;
- uint32 total_player_time = 0;
- uint32 level = 0;
- uint32 latency = 0;
-
- // get additional information from Player object
- if(target)
- {
- targetGUID = target->GetGUID();
- name = target->GetName(); // re-read for case getSelectedPlayer() target
- accId = target->GetSession()->GetAccountId();
- money = target->GetMoney();
- total_player_time = target->GetTotalPlayedTime();
- level = target->getLevel();
- latency = target->GetSession()->GetLatency();
- }
- // get additional information from DB
- else
- {
- QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));
- if (!result)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
- Field *fields = result->Fetch();
- total_player_time = fields[0].GetUInt32();
- delete result;
-
- Tokens data;
- if (!Player::LoadValuesArrayFromDB(data,targetGUID))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
- level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
- accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
- }
-
- std::string username = GetTrinityString(LANG_ERROR);
- std::string last_ip = GetTrinityString(LANG_ERROR);
- uint32 security = 0;
- std::string last_login = GetTrinityString(LANG_ERROR);
-
- QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
- if(result)
- {
- Field* fields = result->Fetch();
- username = fields[0].GetCppString();
- security = fields[1].GetUInt32();
-
- if(!m_session || m_session->GetSecurity() >= security)
- {
- last_ip = fields[2].GetCppString();
- last_login = fields[3].GetCppString();
- }
- else
- {
- last_ip = "-";
- last_login = "-";
- }
-
- delete result;
- }
-
- PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
-
- std::string timeStr = secsToTimeString(total_player_time,true,true);
- uint32 gold = money /GOLD;
- uint32 silv = (money % GOLD) / SILVER;
- uint32 copp = (money % GOLD) % SILVER;
- PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
-
- if ( py && strncmp(py, "rep", 3) == 0 )
- {
- if(!target)
- {
- // rep option not implemented for offline case
- SendSysMessage(LANG_PINFO_NO_REP);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* FactionName;
- for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
- {
- FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
- if (factionEntry)
- FactionName = factionEntry->name[m_session->GetSessionDbcLocale()];
- else
- FactionName = "#Not found#";
- ReputationRank rank = target->GetReputationRank(factionEntry);
- std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
- std::ostringstream ss;
- ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
-
- if(itr->second.Flags & FACTION_FLAG_VISIBLE)
- ss << GetTrinityString(LANG_FACTION_VISIBLE);
- if(itr->second.Flags & FACTION_FLAG_AT_WAR)
- ss << GetTrinityString(LANG_FACTION_ATWAR);
- if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
- ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
- if(itr->second.Flags & FACTION_FLAG_HIDDEN)
- ss << GetTrinityString(LANG_FACTION_HIDDEN);
- if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
- ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
- if(itr->second.Flags & FACTION_FLAG_INACTIVE)
- ss << GetTrinityString(LANG_FACTION_INACTIVE);
-
- SendSysMessage(ss.str().c_str());
- }
- }
- return true;
-}
-
-//show tickets
-void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
-{
- std::string name;
- if(!objmgr.GetPlayerNameByGUID(guid,name))
- name = GetTrinityString(LANG_UNKNOWN);
-
- PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text);
-}
-
-//ticket commands
-bool ChatHandler::HandleTicketCommand(const char* args)
-{
- char* px = strtok((char*)args, " ");
-
- // ticket<end>
- if (!px)
- {
- if(!m_session)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- size_t count = ticketmgr.GetTicketCount();
-
- bool accept = m_session->GetPlayer()->isAcceptTickets();
-
- PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ? GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF));
- return true;
- }
-
- // ticket on
- if(strncmp(px,"on",3) == 0)
- {
- if(!m_session)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- m_session->GetPlayer()->SetAcceptTicket(true);
- SendSysMessage(LANG_COMMAND_TICKETON);
- return true;
- }
-
- // ticket off
- if(strncmp(px,"off",4) == 0)
- {
- if(!m_session)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- m_session->GetPlayer()->SetAcceptTicket(false);
- SendSysMessage(LANG_COMMAND_TICKETOFF);
- return true;
- }
-
- // ticket #num
- int num = atoi(px);
- if(num > 0)
- {
- QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
-
- if(!result)
- {
- PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
- SetSentErrorMessage(true);
- return false;
- }
-
- Field* fields = result->Fetch();
-
- uint32 guid = fields[0].GetUInt32();
- char const* text = fields[1].GetString();
- char const* time = fields[2].GetString();
-
- ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
- delete result;
- return true;
- }
-
- std::string name = px;
-
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 guid = objmgr.GetPlayerGUIDByName(name);
-
- if(!guid)
- return false;
-
- // ticket $char_name
- GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid));
- if(!ticket)
- return false;
-
- std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
-
- ShowTicket(guid, ticket->GetText(), time.c_str());
-
- return true;
-}
-
-//dell all tickets
-bool ChatHandler::HandleDelTicketCommand(const char *args)
-{
- char* px = strtok((char*)args, " ");
- if (!px)
- return false;
-
- // delticket all
- if(strncmp(px,"all",4) == 0)
- {
- ticketmgr.DeleteAll();
- SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
- return true;
- }
-
- int num = (uint32)atoi(px);
-
- // delticket #num
- if(num > 0)
- {
- QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
- if(!result)
- {
- PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
- SetSentErrorMessage(true);
- return false;
- }
-
- Field* fields = result->Fetch();
-
- uint32 guid = fields[0].GetUInt32();
- delete result;
-
- ticketmgr.Delete(guid);
-
- //notify player
- if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
- {
- pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
- PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, pl->GetName());
- }
- else
- PSendSysMessage(LANG_COMMAND_TICKETDEL);
-
- return true;
- }
-
- std::string name = px;
-
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 guid = objmgr.GetPlayerGUIDByName(name);
-
- if(!guid)
- return false;
-
- // delticket $char_name
- ticketmgr.Delete(GUID_LOPART(guid));
-
- // notify players about ticket deleting
- if(Player* sender = objmgr.GetPlayer(guid))
- sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
-
- PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
- return true;
-}
-
-//set spawn dist of creature
-bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
-{
- if(!*args)
- return false;
-
- float option = atof((char*)args);
- if (option < 0.0f)
- {
- SendSysMessage(LANG_BAD_VALUE);
- return false;
- }
-
- MovementGeneratorType mtype = IDLE_MOTION_TYPE;
- if (option >0.0f)
- mtype = RANDOM_MOTION_TYPE;
-
- Creature *pCreature = getSelectedCreature();
- uint32 u_guidlow = 0;
-
- if (pCreature)
- u_guidlow = pCreature->GetDBTableGUIDLow();
- else
- return false;
-
- pCreature->SetRespawnRadius((float)option);
- pCreature->SetDefaultMovementType(mtype);
- pCreature->GetMotionMaster()->Initialize();
- if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- pCreature->setDeathState(JUST_DIED);
- pCreature->Respawn();
- }
-
- WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
- PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
- return true;
-}
-
-bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
-{
- if(!*args)
- return false;
-
- char* stime = strtok((char*)args, " ");
-
- if (!stime)
- return false;
-
- int i_stime = atoi((char*)stime);
-
- if (i_stime < 0)
- {
- SendSysMessage(LANG_BAD_VALUE);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature *pCreature = getSelectedCreature();
- uint32 u_guidlow = 0;
-
- if (pCreature)
- u_guidlow = pCreature->GetDBTableGUIDLow();
- else
- return false;
-
- WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
- pCreature->SetRespawnDelay((uint32)i_stime);
- PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
-
- return true;
-}
-
-/**
- * Add a waypoint to a creature.
- *
- * The user can either select an npc or provide its GUID.
- *
- * The user can even select a visual waypoint - then the new waypoint
- * is placed *after* the selected one - this makes insertion of new
- * waypoints possible.
- *
- * eg:
- * .wp add 12345
- * -> adds a waypoint to the npc with the GUID 12345
- *
- * .wp add
- * -> adds a waypoint to the currently selected creature
- *
- *
- * @param args if the user did not provide a GUID, it is NULL
- *
- * @return true - command did succeed, false - something went wrong
- */
-bool ChatHandler::HandleWpAddCommand(const char* args)
-{
- sLog.outDebug("DEBUG: HandleWpAddCommand");
-
- // optional
- char* guid_str = NULL;
-
- if(*args)
- {
- guid_str = strtok((char*)args, " ");
- }
-
- uint32 lowguid = 0;
- uint32 point = 0;
- Creature* target = getSelectedCreature();
- // Did player provide a GUID?
- if (!guid_str)
- {
- sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
-
- // No GUID provided
- // -> Player must have selected a creature
-
- if(!target || target->isPet())
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
- if (target->GetEntry() == VISUAL_WAYPOINT )
- {
- sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
-
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
- target->GetGUIDLow() );
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
- // User selected a visual spawnpoint -> get the NPC
- // Select NPC GUID
- // Since we compare float values, we have to deal with
- // some difficulties.
- // Here we search for all waypoints that only differ in one from 1 thousand
- // (0.001) - There is no other way to compare C++ floats with mySQL floats
- // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
- const char* maxDIFF = "0.01";
- result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
- target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
- SetSentErrorMessage(true);
- return false;
- }
- }
- do
- {
- Field *fields = result->Fetch();
- lowguid = fields[0].GetUInt32();
- point = fields[1].GetUInt32();
- }while( result->NextRow() );
- delete result;
-
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
- if(!target)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- lowguid = target->GetDBTableGUIDLow();
- }
- }
- else
- {
- sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
-
- // GUID provided
- // Warn if player also selected a creature
- // -> Creature selection is ignored <-
- if(target)
- {
- SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
- }
- lowguid = atoi((char*)guid_str);
-
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
- if(!target || target->isPet())
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- // lowguid -> GUID of the NPC
- // point -> number of the waypoint (if not 0)
- sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
-
- sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
-
- Player* player = m_session->GetPlayer();
- WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
-
- // update movement type
- if(target)
- {
- target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- target->GetMotionMaster()->Initialize();
- if(target->isAlive()) // dead creature will reset movement generator at respawn
- {
- target->setDeathState(JUST_DIED);
- target->Respawn();
- }
- target->SaveToDB();
- }
- else
- WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
-
- PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
-
- return true;
-} // HandleWpAddCommand
-
-/**
- * .wp modify emote | spell | text | del | move | add
- *
- * add -> add a WP after the selected visual waypoint
- * User must select a visual waypoint and then issue ".wp modify add"
- *
- * emote <emoteID>
- * User has selected a visual waypoint before.
- * <emoteID> is added to this waypoint. Everytime the
- * NPC comes to this waypoint, the emote is called.
- *
- * emote <GUID> <WPNUM> <emoteID>
- * User has not selected visual waypoint before.
- * For the waypoint <WPNUM> for the NPC with <GUID>
- * an emote <emoteID> is added.
- * Everytime the NPC comes to this waypoint, the emote is called.
- *
- *
- * info <GUID> <WPNUM> -> User did not select a visual waypoint and
- */
-bool ChatHandler::HandleWpModifyCommand(const char* args)
-{
- sLog.outDebug("DEBUG: HandleWpModifyCommand");
-
- if(!*args)
- return false;
-
- // first arg: add del text emote spell waittime move
- char* show_str = strtok((char*)args, " ");
- if (!show_str)
- {
- return false;
- }
-
- std::string show = show_str;
- // Check
- // Remember: "show" must also be the name of a column!
- if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2")
- && (show != "text3") && (show != "text4") && (show != "text5")
- && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
- && (show != "model1") && (show != "model2") && (show != "orientation"))
- {
- return false;
- }
-
- // Next arg is: <GUID> <WPNUM> <ARGUMENT>
-
- // Did user provide a GUID
- // or did the user select a creature?
- // -> variable lowguid is filled with the GUID of the NPC
- uint32 lowguid = 0;
- uint32 point = 0;
- uint32 wpGuid = 0;
- Creature* target = getSelectedCreature();
-
- if(target)
- {
- sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
-
- // Did the user select a visual spawnpoint?
- if (target->GetEntry() != VISUAL_WAYPOINT )
- {
- PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
- SetSentErrorMessage(true);
- return false;
- }
-
- wpGuid = target->GetGUIDLow();
-
- // The visual waypoint
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
- target->GetGUIDLow() );
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
- SetSentErrorMessage(true);
- return false;
- }
- sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
-
- Field *fields = result->Fetch();
- lowguid = fields[0].GetUInt32();
- point = fields[1].GetUInt32();
-
- // Cleanup memory
- sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
- delete result;
- }
- else
- {
- // User did provide <GUID> <WPNUM>
-
- char* guid_str = strtok((char*)NULL, " ");
- if( !guid_str )
- {
- SendSysMessage(LANG_WAYPOINT_NOGUID);
- return false;
- }
- lowguid = atoi((char*)guid_str);
-
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
-
- char* point_str = strtok((char*)NULL, " ");
- if( !point_str )
- {
- SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
- return false;
- }
- point = atoi((char*)point_str);
-
- PSendSysMessage("DEBUG: wpNumber provided: %d", point);
-
- // Now we need the GUID of the visual waypoint
- // -> "del", "move", "add" command
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
- if (!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
- SetSentErrorMessage(true);
- return false;
- }
-
- Field *fields = result->Fetch();
- wpGuid = fields[0].GetUInt32();
-
- // Free memory
- delete result;
- }
-
- char* arg_str = NULL;
- // Check for argument
- if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
- {
- // Text is enclosed in "<>", all other arguments not
- if( show.find("text") != std::string::npos )
- arg_str = strtok((char*)NULL, "<>");
- else
- arg_str = strtok((char*)NULL, " ");
-
- if( !arg_str)
- {
- PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
- return false;
- }
- }
-
- sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
-
- // wpGuid -> GUID of the waypoint creature
- // lowguid -> GUID of the NPC
- // point -> waypoint number
-
- // Special functions:
- // add - move - del -> no args commands
- // Add a waypoint after the selected visual
- if(show == "add" && target)
- {
- PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
-
- // Get the creature for which we read the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
-
- if( !npcCreature )
- {
- PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
-
- // What to do:
- // Add the visual spawnpoint (DB only)
- // Adjust the waypoints
- // Respawn the owner of the waypoints
- sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
-
- Player* chr = m_session->GetPlayer();
- Map *map = chr->GetMap();
-
- if(npcCreature)
- {
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
- }
-
- // create the waypoint creature
- wpGuid = 0;
- Creature* wpCreature = new Creature;
- if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
- delete wpCreature;
- }
- else
- {
- wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
-
- if(!wpCreature->IsPositionValid())
- {
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
- delete wpCreature;
- }
- else
- {
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
- map->Add(wpCreature);
- wpGuid = wpCreature->GetGUIDLow();
- }
- }
-
- WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
-
- if(!wpGuid)
- return false;
-
- PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
- return true;
- } // add
-
- if(show == "del" && target)
- {
- PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
-
- // Get the creature for which we read the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
-
- // wpCreature
- Creature* wpCreature = NULL;
- if( wpGuid != 0 )
- {
- wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
- wpCreature->DeleteFromDB();
- wpCreature->CleanupsBeforeDelete();
- wpCreature->AddObjectToRemoveList();
- }
-
- // What to do:
- // Remove the visual spawnpoint
- // Adjust the waypoints
- // Respawn the owner of the waypoints
-
- WaypointMgr.DeleteNode(lowguid, point);
-
- if(npcCreature)
- {
- // Any waypoints left?
- QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
- if(!result2)
- {
- npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
- }
- else
- {
- npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- delete result2;
- }
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
- npcCreature->SaveToDB();
- }
-
- PSendSysMessage(LANG_WAYPOINT_REMOVED);
- return true;
- } // del
-
- if(show == "move" && target)
- {
- PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
-
- Player *chr = m_session->GetPlayer();
- Map *map = chr->GetMap();
- {
- // Get the creature for which we read the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
-
- // wpCreature
- Creature* wpCreature = NULL;
- // What to do:
- // Move the visual spawnpoint
- // Respawn the owner of the waypoints
- if( wpGuid != 0 )
- {
- wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
- wpCreature->DeleteFromDB();
- wpCreature->CleanupsBeforeDelete();
- wpCreature->AddObjectToRemoveList();
- // re-create
- Creature* wpCreature2 = new Creature;
- if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
- delete wpCreature2;
- return false;
- }
-
- wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
-
- if(!wpCreature2->IsPositionValid())
- {
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());
- delete wpCreature2;
- return false;
- }
-
- wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
- map->Add(wpCreature2);
- //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
- }
-
- WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
-
- if(npcCreature)
- {
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
- }
- PSendSysMessage(LANG_WAYPOINT_CHANGED);
- }
- return true;
- } // move
-
- // Create creature - npc that has the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
-
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
- if(npcCreature)
- {
- npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
- }
- PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
-
- return true;
-}
-
-/**
- * .wp show info | on | off
- *
- * info -> User has selected a visual waypoint before
- *
- * info <GUID> <WPNUM> -> User did not select a visual waypoint and
- * provided the GUID of the NPC and the number of
- * the waypoint.
- *
- * on -> User has selected an NPC; all visual waypoints for this
- * NPC are added to the world
- *
- * on <GUID> -> User did not select an NPC - instead the GUID of the
- * NPC is provided. All visual waypoints for this NPC
- * are added from the world.
- *
- * off -> User has selected an NPC; all visual waypoints for this
- * NPC are removed from the world.
- *
- * on <GUID> -> User did not select an NPC - instead the GUID of the
- * NPC is provided. All visual waypoints for this NPC
- * are removed from the world.
- *
- *
- */
-bool ChatHandler::HandleWpShowCommand(const char* args)
-{
- sLog.outDebug("DEBUG: HandleWpShowCommand");
-
- if(!*args)
- return false;
-
- // first arg: on, off, first, last
- char* show_str = strtok((char*)args, " ");
- if (!show_str)
- {
- return false;
- }
- // second arg: GUID (optional, if a creature is selected)
- char* guid_str = strtok((char*)NULL, " ");
- sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
- //if (!guid_str) {
- // return false;
- //}
-
- // Did user provide a GUID
- // or did the user select a creature?
- // -> variable lowguid is filled with the GUID
- Creature* target = getSelectedCreature();
- // Did player provide a GUID?
- if (!guid_str)
- {
- sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
- // No GUID provided
- // -> Player must have selected a creature
-
- if(!target)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
- // GUID provided
- // Warn if player also selected a creature
- // -> Creature selection is ignored <-
- if(target)
- {
- SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
- }
-
- uint32 lowguid = atoi((char*)guid_str);
-
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
-
- if(!target)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
-
- uint32 lowguid = target->GetDBTableGUIDLow();
-
- std::string show = show_str;
- uint32 Maxpoint;
-
- sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid, show_str);
-
- // Show info for the selected waypoint
- if(show == "info")
- {
- PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
-
- // Check if the user did specify a visual waypoint
- if( target->GetEntry() != VISUAL_WAYPOINT )
- {
- PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
- SetSentErrorMessage(true);
- return false;
- }
-
- //PSendSysMessage("wp on, GUID: %u", lowguid);
-
- //pCreature->GetPositionX();
-
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
- target->GetGUIDLow() );
- if(!result)
- {
- // Since we compare float values, we have to deal with
- // some difficulties.
- // Here we search for all waypoints that only differ in one from 1 thousand
- // (0.001) - There is no other way to compare C++ floats with mySQL floats
- // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
- const char* maxDIFF = "0.01";
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
-
- result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
- target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- do
- {
- Field *fields = result->Fetch();
- uint32 creGUID = fields[0].GetUInt32();
- uint32 point = fields[1].GetUInt32();
- int waittime = fields[2].GetUInt32();
- uint32 emote = fields[3].GetUInt32();
- uint32 spell = fields[4].GetUInt32();
- const char * text1 = fields[5].GetString();
- const char * text2 = fields[6].GetString();
- const char * text3 = fields[7].GetString();
- const char * text4 = fields[8].GetString();
- const char * text5 = fields[9].GetString();
- uint32 model1 = fields[10].GetUInt32();
- uint32 model2 = fields[11].GetUInt32();
-
- // Get the creature for which we read the waypoint
- Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
-
- PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
- PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
- PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
- PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
- PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
- PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
-
- }while( result->NextRow() );
- // Cleanup memory
- delete result;
- return true;
- }
-
- if(show == "on")
- {
- PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- // Delete all visuals for this NPC
- QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
- if(result2)
- {
- bool hasError = false;
- do
- {
- Field *fields = result2->Fetch();
- uint32 wpguid = fields[0].GetUInt32();
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
-
- if(!pCreature)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
- hasError = true;
- WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
- }
- else
- {
- pCreature->DeleteFromDB();
- pCreature->CleanupsBeforeDelete();
- pCreature->AddObjectToRemoveList();
- }
-
- }while( result2->NextRow() );
- delete result2;
- if( hasError )
- {
- PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
- }
- }
-
- do
- {
- Field *fields = result->Fetch();
- uint32 point = fields[0].GetUInt32();
- float x = fields[1].GetFloat();
- float y = fields[2].GetFloat();
- float z = fields[3].GetFloat();
-
- uint32 id = VISUAL_WAYPOINT;
-
- Player *chr = m_session->GetPlayer();
- Map *map = chr->GetMap();
- float o = chr->GetOrientation();
-
- Creature* wpCreature = new Creature;
- if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
- delete wpCreature;
- delete result;
- return false;
- }
-
- wpCreature->Relocate(x, y, z, o);
-
- if(!wpCreature->IsPositionValid())
- {
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
- delete wpCreature;
- delete result;
- return false;
- }
-
- wpCreature->SetVisibility(VISIBILITY_OFF);
- sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
- // set "wpguid" column to the visual waypoint
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
-
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
- map->Add(wpCreature);
- //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
- }while( result->NextRow() );
-
- // Cleanup memory
- delete result;
- return true;
- }
-
- if(show == "first")
- {
- PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- Field *fields = result->Fetch();
- float x = fields[0].GetFloat();
- float y = fields[1].GetFloat();
- float z = fields[2].GetFloat();
- uint32 id = VISUAL_WAYPOINT;
-
- Player *chr = m_session->GetPlayer();
- float o = chr->GetOrientation();
- Map *map = chr->GetMap();
-
- Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
- delete pCreature;
- delete result;
- return false;
- }
-
- pCreature->Relocate(x, y, z, o);
-
- if(!pCreature->IsPositionValid())
- {
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
- delete pCreature;
- delete result;
- return false;
- }
-
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
- map->Add(pCreature);
- //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
-
- // Cleanup memory
- delete result;
- return true;
- }
-
- if(show == "last")
- {
- PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
- if( result )
- {
- Maxpoint = (*result)[0].GetUInt32();
-
- delete result;
- }
- else
- Maxpoint = 0;
-
- result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- Field *fields = result->Fetch();
- float x = fields[0].GetFloat();
- float y = fields[1].GetFloat();
- float z = fields[2].GetFloat();
- uint32 id = VISUAL_WAYPOINT;
-
- Player *chr = m_session->GetPlayer();
- float o = chr->GetOrientation();
- Map *map = chr->GetMap();
-
- Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
- delete pCreature;
- delete result;
- return false;
- }
-
- pCreature->Relocate(x, y, z, o);
-
- if(!pCreature->IsPositionValid())
- {
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
- delete pCreature;
- delete result;
- return false;
- }
-
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
- map->Add(pCreature);
- //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
- // Cleanup memory
- delete result;
- return true;
- }
-
- if(show == "off")
- {
- QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
- if(!result)
- {
- SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
- SetSentErrorMessage(true);
- return false;
- }
- bool hasError = false;
- do
- {
- Field *fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
-
- //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
-
- if(!pCreature)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
- hasError = true;
- WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
- }
- else
- {
- pCreature->DeleteFromDB();
- pCreature->CleanupsBeforeDelete();
- pCreature->AddObjectToRemoveList();
- }
- }while(result->NextRow());
- // set "wpguid" column to "empty" - no visual waypoint spawned
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
-
- if( hasError )
- {
- PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
- }
-
- SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
- // Cleanup memory
- delete result;
-
- return true;
- }
-
- PSendSysMessage("DEBUG: wpshow - no valid command found");
-
- return true;
-} // HandleWpShowCommand
-
-bool ChatHandler::HandleWpExportCommand(const char *args)
-{
- if(!*args)
- return false;
-
- // Next arg is: <GUID> <ARGUMENT>
-
- // Did user provide a GUID
- // or did the user select a creature?
- // -> variable lowguid is filled with the GUID of the NPC
- uint32 lowguid = 0;
- Creature* target = getSelectedCreature();
- char* arg_str = NULL;
- if (target)
- {
- if (target->GetEntry() != VISUAL_WAYPOINT)
- lowguid = target->GetGUIDLow();
- else
- {
- QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
- if (!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
- return true;
- }
- Field *fields = result->Fetch();
- lowguid = fields[0].GetUInt32();;
- delete result;
- }
-
- arg_str = strtok((char*)args, " ");
- }
- else
- {
- // user provided <GUID>
- char* guid_str = strtok((char*)args, " ");
- if( !guid_str )
- {
- SendSysMessage(LANG_WAYPOINT_NOGUID);
- return false;
- }
- lowguid = atoi((char*)guid_str);
-
- arg_str = strtok((char*)NULL, " ");
- }
-
- if( !arg_str)
- {
- PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
- return false;
- }
-
- PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery(
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
-
- if (!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
- SetSentErrorMessage(true);
- return false;
- }
-
- std::ofstream outfile;
- outfile.open (arg_str);
-
- do
- {
- Field *fields = result->Fetch();
-
- outfile << "INSERT INTO creature_movement ";
- outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
-
- outfile << "( ";
- outfile << fields[15].GetUInt32(); // id
- outfile << ", ";
- outfile << fields[0].GetUInt32(); // point
- outfile << ", ";
- outfile << fields[1].GetFloat(); // position_x
- outfile << ", ";
- outfile << fields[2].GetFloat(); // position_y
- outfile << ", ";
- outfile << fields[3].GetUInt32(); // position_z
- outfile << ", ";
- outfile << fields[4].GetUInt32(); // orientation
- outfile << ", ";
- outfile << fields[5].GetUInt32(); // model1
- outfile << ", ";
- outfile << fields[6].GetUInt32(); // model2
- outfile << ", ";
- outfile << fields[7].GetUInt16(); // waittime
- outfile << ", ";
- outfile << fields[8].GetUInt32(); // emote
- outfile << ", ";
- outfile << fields[9].GetUInt32(); // spell
- outfile << ", ";
- const char *tmpChar = fields[10].GetString();
- if( !tmpChar )
- {
- outfile << "NULL"; // text1
- }
- else
- {
- outfile << "'";
- outfile << tmpChar; // text1
- outfile << "'";
- }
- outfile << ", ";
- tmpChar = fields[11].GetString();
- if( !tmpChar )
- {
- outfile << "NULL"; // text2
- }
- else
- {
- outfile << "'";
- outfile << tmpChar; // text2
- outfile << "'";
- }
- outfile << ", ";
- tmpChar = fields[12].GetString();
- if( !tmpChar )
- {
- outfile << "NULL"; // text3
- }
- else
- {
- outfile << "'";
- outfile << tmpChar; // text3
- outfile << "'";
- }
- outfile << ", ";
- tmpChar = fields[13].GetString();
- if( !tmpChar )
- {
- outfile << "NULL"; // text4
- }
- else
- {
- outfile << "'";
- outfile << tmpChar; // text4
- outfile << "'";
- }
- outfile << ", ";
- tmpChar = fields[14].GetString();
- if( !tmpChar )
- {
- outfile << "NULL"; // text5
- }
- else
- {
- outfile << "'";
- outfile << tmpChar; // text5
- outfile << "'";
- }
- outfile << ");\n ";
-
- } while( result->NextRow() );
- delete result;
-
- PSendSysMessage(LANG_WAYPOINT_EXPORTED);
- outfile.close();
-
- return true;
-}
-
-bool ChatHandler::HandleWpImportCommand(const char *args)
-{
- if(!*args)
- return false;
-
- char* arg_str = strtok((char*)args, " ");
- if (!arg_str)
- return false;
-
- std::string line;
- std::ifstream infile (arg_str);
- if (infile.is_open())
- {
- while (! infile.eof() )
- {
- getline (infile,line);
- //cout << line << endl;
- QueryResult *result = WorldDatabase.Query(line.c_str());
- delete result;
- }
- infile.close();
- }
- PSendSysMessage(LANG_WAYPOINT_IMPORTED);
-
- return true;
-}
-
-//rename characters
-bool ChatHandler::HandleRenameCommand(const char* args)
-{
- Player* target = NULL;
- uint64 targetGUID = 0;
- std::string oldname;
-
- char* px = strtok((char*)args, " ");
-
- if(px)
- {
- oldname = px;
-
- if(!normalizePlayerName(oldname))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- target = objmgr.GetPlayer(oldname.c_str());
-
- if (!target)
- targetGUID = objmgr.GetPlayerGUIDByName(oldname);
- }
-
- if(!target && !targetGUID)
- {
- target = getSelectedPlayer();
- }
-
- if(!target && !targetGUID)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- if(target)
- {
- PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
- target->SetAtLoginFlag(AT_LOGIN_RENAME);
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
- }
- else
- {
- PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
- }
-
- return true;
-}
-
-//spawn go
-bool ChatHandler::HandleGameObjectCommand(const char* args)
-{
- if (!*args)
- return false;
-
- char* pParam1 = strtok((char*)args, " ");
- if (!pParam1)
- return false;
-
- uint32 id = atoi((char*)pParam1);
- if(!id)
- return false;
-
- char* spawntimeSecs = strtok(NULL, " ");
-
- const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
-
- if (!goI)
- {
- PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
- SetSentErrorMessage(true);
- return false;
- }
-
- Player *chr = m_session->GetPlayer();
- float x = float(chr->GetPositionX());
- float y = float(chr->GetPositionY());
- float z = float(chr->GetPositionZ());
- float o = float(chr->GetOrientation());
- Map *map = chr->GetMap();
-
- float rot2 = sin(o/2);
- float rot3 = cos(o/2);
-
- GameObject* pGameObj = new GameObject;
- uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
-
- if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
- {
- delete pGameObj;
- return false;
- }
-
- if( spawntimeSecs )
- {
- uint32 value = atoi((char*)spawntimeSecs);
- pGameObj->SetRespawnTime(value);
- //sLog.outDebug("*** spawntimeSecs: %d", value);
- }
-
- // fill the gameobject data and save to the db
- pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
-
- // this will generate a new guid if the object is in an instance
- if(!pGameObj->LoadFromDB(db_lowGUID, map))
- {
- delete pGameObj;
- return false;
- }
-
- sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
-
- map->Add(pGameObj);
-
- // TODO: is it really necessary to add both the real and DB table guid here ?
- objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
-
- PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
- return true;
-}
-
-//show animation
-bool ChatHandler::HandleAnimCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint32 anim_id = atoi((char*)args);
- m_session->GetPlayer()->HandleEmoteCommand(anim_id);
- return true;
-}
-
-//change standstate
-bool ChatHandler::HandleStandStateCommand(const char* args)
-{
- if (!*args)
- return false;
-
- uint32 anim_id = atoi((char*)args);
- m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
-
- return true;
-}
-
-bool ChatHandler::HandleAddHonorCommand(const char* args)
-{
- if (!*args)
- return false;
-
- Player *target = getSelectedPlayer();
- if(!target)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 amount = (uint32)atoi(args);
- target->RewardHonor(NULL, 1, amount);
- return true;
-}
-
-bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
-{
- Unit *target = getSelectedUnit();
- if(!target)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- m_session->GetPlayer()->RewardHonor(target, 1);
- return true;
-}
-
-bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
-{
- Player *target = getSelectedPlayer();
- if(!target)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- target->UpdateHonorFields();
- return true;
-}
-
-bool ChatHandler::HandleLookupEventCommand(const char* args)
-{
- if(!*args)
- return false;
-
- std::string namepart = args;
- std::wstring wnamepart;
-
- // converting string that we try to find to lower case
- if(!Utf8toWStr(namepart,wnamepart))
- return false;
-
- wstrToLower(wnamepart);
-
- uint32 counter = 0;
-
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
-
- for(uint32 id = 0; id < events.size(); ++id )
- {
- GameEventData const& eventData = events[id];
-
- std::string descr = eventData.description;
- if(descr.empty())
- continue;
-
- if (Utf8FitTo(descr, wnamepart))
- {
- char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : "";
-
- if(m_session)
- PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
- else
- PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
-
- ++counter;
- }
- }
-
- if (counter==0)
- SendSysMessage(LANG_NOEVENTFOUND);
-
- return true;
-}
-
-bool ChatHandler::HandleEventActiveListCommand(const char* args)
-{
- uint32 counter = 0;
-
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
-
- char const* active = GetTrinityString(LANG_ACTIVE);
-
- for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
- {
- uint32 event_id = *itr;
- GameEventData const& eventData = events[event_id];
-
- if(m_session)
- PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
- else
- PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
-
- ++counter;
- }
-
- if (counter==0)
- SendSysMessage(LANG_NOEVENTFOUND);
-
- return true;
-}
-
-bool ChatHandler::HandleEventInfoCommand(const char* args)
-{
- if(!*args)
- return false;
-
- // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameevent");
- if(!cId)
- return false;
-
- uint32 event_id = atoi(cId);
-
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
-
- if(event_id >=events.size())
- {
- SendSysMessage(LANG_EVENT_NOT_EXIST);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameEventData const& eventData = events[event_id];
- if(!eventData.isValid())
- {
- SendSysMessage(LANG_EVENT_NOT_EXIST);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
- bool active = activeEvents.find(event_id) != activeEvents.end();
- char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
-
- std::string startTimeStr = TimeToTimestampStr(eventData.start);
- std::string endTimeStr = TimeToTimestampStr(eventData.end);
-
- uint32 delay = gameeventmgr.NextCheck(event_id);
- time_t nextTime = time(NULL)+delay;
- std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
-
- std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
- std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
-
- PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
- startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
- nextStr.c_str());
- return true;
-}
-
-bool ChatHandler::HandleEventStartCommand(const char* args)
-{
- if(!*args)
- return false;
-
- // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameevent");
- if(!cId)
- return false;
-
- int32 event_id = atoi(cId);
-
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
-
- if(event_id < 1 || event_id >=events.size())
- {
- SendSysMessage(LANG_EVENT_NOT_EXIST);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameEventData const& eventData = events[event_id];
- if(!eventData.isValid())
- {
- SendSysMessage(LANG_EVENT_NOT_EXIST);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
- if(activeEvents.find(event_id) != activeEvents.end())
- {
- PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- gameeventmgr.StartEvent(event_id,true);
- return true;
-}
-
-bool ChatHandler::HandleEventStopCommand(const char* args)
-{
- if(!*args)
- return false;
-
- // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args,"Hgameevent");
- if(!cId)
- return false;
-
- int32 event_id = atoi(cId);
-
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
-
- if(event_id < 1 || event_id >=events.size())
- {
- SendSysMessage(LANG_EVENT_NOT_EXIST);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameEventData const& eventData = events[event_id];
- if(!eventData.isValid())
- {
- SendSysMessage(LANG_EVENT_NOT_EXIST);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
-
- if(activeEvents.find(event_id) == activeEvents.end())
- {
- PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- gameeventmgr.StopEvent(event_id,true);
- return true;
-}
-
-bool ChatHandler::HandleCombatStopCommand(const char* args)
-{
- Player *player;
-
- if(*args)
- {
- std::string playername = args;
-
- if(!normalizePlayerName(playername))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- player = objmgr.GetPlayer(playername.c_str());
-
- if(!player)
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- player = getSelectedPlayer();
-
- if (!player)
- player = m_session->GetPlayer();
- }
-
- player->CombatStop();
- player->getHostilRefManager().deleteReferences();
- return true;
-}
-
-bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
-{
- uint32 classmask = m_session->GetPlayer()->getClassMask();
-
- for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
- {
- SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
- if( !skillInfo )
- continue;
-
- if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
- {
- for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
- {
- SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
- if( !skillLine )
- continue;
-
- // skip racial skills
- if( skillLine->racemask != 0 )
- continue;
-
- // skip wrong class skills
- if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
- continue;
-
- if( skillLine->skillId != i || skillLine->forward_spellid )
- continue;
-
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
- if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
- continue;
-
- m_session->GetPlayer()->learnSpell(skillLine->spellId);
- }
- }
- }
-
- SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
- return true;
-}
-
-bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
-{
- // Learns all recipes of specified profession and sets skill to max
- // Example: .learn all_recipes enchanting
-
- Player* target = getSelectedPlayer();
- if( !target )
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- return false;
- }
-
- if (!*args)
- return false;
-
- std::wstring wnamepart;
-
- if(!Utf8toWStr(args,wnamepart))
- return false;
-
- uint32 counter = 0; // Counter for figure out that we found smth.
-
- // converting string that we try to find to lower case
- wstrToLower( wnamepart );
-
- uint32 classmask = m_session->GetPlayer()->getClassMask();
-
- for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
- {
- SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
- if( !skillInfo )
- continue;
-
- if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
- skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
- continue;
-
- int loc = m_session->GetSessionDbcLocale();
- std::string name = skillInfo->name[loc];
-
- if(Utf8FitTo(name, wnamepart))
- {
- for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
- {
- SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
- if( !skillLine )
- continue;
-
- if( skillLine->skillId != i || skillLine->forward_spellid )
- continue;
-
- // skip racial skills
- if( skillLine->racemask != 0 )
- continue;
-
- // skip wrong class skills
- if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
- continue;
-
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
- if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
- continue;
-
- if( !target->HasSpell(spellInfo->Id) )
- m_session->GetPlayer()->learnSpell(skillLine->spellId);
- }
-
- uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
- target->SetSkill(skillInfo->id, maxLevel, maxLevel);
- PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
- return true;
- }
- }
-
- return false;
-}
-
-bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
-{
-
- if (!*args)
- return false;
-
- std::string ip = strtok ((char*)args, " ");
- char* limit_str = strtok (NULL, " ");
- int32 limit = limit_str ? atoi (limit_str) : -1;
-
- loginDatabase.escape_string (ip);
-
- QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
-
- return LookupPlayerSearchCommand (result,limit);
-}
-
-bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
-{
- if (!*args)
- return false;
-
- std::string account = strtok ((char*)args, " ");
- char* limit_str = strtok (NULL, " ");
- int32 limit = limit_str ? atoi (limit_str) : -1;
-
- if (!AccountMgr::normilizeString (account))
- return false;
-
- loginDatabase.escape_string (account);
-
- QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
-
- return LookupPlayerSearchCommand (result,limit);
-}
-
-bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
-{
-
- if (!*args)
- return false;
-
- std::string email = strtok ((char*)args, " ");
- char* limit_str = strtok (NULL, " ");
- int32 limit = limit_str ? atoi (limit_str) : -1;
-
- loginDatabase.escape_string (email);
-
- QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
-
- return LookupPlayerSearchCommand (result,limit);
-}
-
-bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
-{
- if(!result)
- {
- PSendSysMessage(LANG_NO_PLAYERS_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- int i =0;
- do
- {
- Field* fields = result->Fetch();
- uint32 acc_id = fields[0].GetUInt32();
- std::string acc_name = fields[1].GetCppString();
-
- QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
- if(chars)
- {
- PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
-
- uint64 guid = 0;
- std::string name;
-
- do
- {
- Field* charfields = chars->Fetch();
- guid = charfields[0].GetUInt64();
- name = charfields[1].GetCppString();
-
- PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
- ++i;
-
- } while( chars->NextRow() && ( limit == -1 || i < limit ) );
-
- delete chars;
- }
- } while(result->NextRow());
-
- delete result;
-
- return true;
-}
-
-/// Triggering corpses expire check in world
-bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
-{
- CorpsesErase();
- return true;
-}
-
-bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
-{
- Player *target = getSelectedPlayer();
-
- if(!target)
- {
- PSendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
- }
-
- // Repair items
- target->DurabilityRepairAll(false, 0, false);
-
- PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName());
- if(needReportToTarget(target))
- ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName());
- return true;
-}
-
-bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
-{
- Player *player = m_session->GetPlayer();
- Creature *creature = getSelectedCreature();
-
- if(!creature)
- {
- PSendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- // Follow player - Using pet's default dist and angle
- creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
-
- PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
- return true;
-}
-
-bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
-{
- Player *player = m_session->GetPlayer();
- Creature *creature = getSelectedCreature();
-
- if(!creature)
- {
- PSendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (creature->GetMotionMaster()->empty() ||
- creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
- {
- PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
- SetSentErrorMessage(true);
- return false;
- }
-
- TargetedMovementGenerator<Creature> const* mgen
- = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
-
- if(mgen->GetTarget()!=player)
- {
- PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
- SetSentErrorMessage(true);
- return false;
- }
-
- // reset movement
- creature->GetMotionMaster()->MovementExpired(true);
-
- PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
- return true;
-}
-
-bool ChatHandler::HandleCreatePetCommand(const char* args)
-{
- Player *player = m_session->GetPlayer();
- Creature *creatureTarget = getSelectedCreature();
-
- if(!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER)
- {
- PSendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creatureTarget->GetEntry());
- // Creatures with family 0 crashes the server
- if(cInfo->family == 0)
- {
- PSendSysMessage("This creature cannot be tamed. (family id: 0).");
- SetSentErrorMessage(true);
- return false;
- }
-
- if(player->GetPetGUID())
- {
- PSendSysMessage("You already have a pet");
- SetSentErrorMessage(true);
- return false;
- }
-
- // Everything looks OK, create new pet
- Pet* pet = new Pet(HUNTER_PET);
-
- if(!pet->CreateBaseAtCreature(creatureTarget))
- {
- delete pet;
- PSendSysMessage("Error 1");
- return false;
- }
-
- creatureTarget->setDeathState(JUST_DIED);
- creatureTarget->RemoveCorpse();
- creatureTarget->SetHealth(0); // just for nice GM-mode view
-
- pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, player->GetGUID());
- pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
- pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());
-
- if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
- {
- sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
- PSendSysMessage("Error 2");
- return false;
- }
-
- // prepare visual effect for levelup
- pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
-
- pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
- // this enables pet details window (Shift+P)
- pet->AIM_Initialize();
- pet->InitPetCreateSpells();
- pet->SetHealth(pet->GetMaxHealth());
-
- MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet);
-
- // visual effect for levelup
- pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
-
- player->SetPet(pet);
- pet->SavePetToDB(PET_SAVE_AS_CURRENT);
- player->PetSpellInitialize();
-
- return true;
-}
-
-bool ChatHandler::HandlePetLearnCommand(const char* args)
-{
- if(!*args)
- return false;
-
- Player *plr = m_session->GetPlayer();
- Pet *pet = plr->GetPet();
-
- if(!pet)
- {
- PSendSysMessage("You have no pet");
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 spellId = extractSpellIdFromLink((char*)args);
-
- if(!spellId || !sSpellStore.LookupEntry(spellId))
- return false;
-
- // Check if pet already has it
- if(pet->HasSpell(spellId))
- {
- PSendSysMessage("Pet already has spell: %u", spellId);
- SetSentErrorMessage(true);
- return false;
- }
-
- // Check if spell is valid
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
- if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo))
- {
- PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spellId);
- SetSentErrorMessage(true);
- return false;
- }
-
- pet->learnSpell(spellId);
-
- PSendSysMessage("Pet has learned spell %u", spellId);
- return true;
-}
-
-bool ChatHandler::HandlePetUnlearnCommand(const char *args)
-{
- if(!*args)
- return false;
-
- Player *plr = m_session->GetPlayer();
- Pet *pet = plr->GetPet();
-
- if(!pet)
- {
- PSendSysMessage("You have no pet");
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 spellId = extractSpellIdFromLink((char*)args);
-
- if(pet->HasSpell(spellId))
- pet->removeSpell(spellId);
- else
- PSendSysMessage("Pet doesn't have that spell");
-
- return true;
-}
-
-bool ChatHandler::HandlePetTpCommand(const char *args)
-{
- if(!*args)
- return false;
-
- Player *plr = m_session->GetPlayer();
- Pet *pet = plr->GetPet();
-
- if(!pet)
- {
- PSendSysMessage("You have no pet");
- SetSentErrorMessage(true);
- return false;
- }
-
- uint32 tp = atol(args);
-
- pet->SetTP(tp);
-
- PSendSysMessage("Pet's tp changed to %u", tp);
- return true;
-}
-
-bool ChatHandler::HandleActivateObjectCommand(const char *args)
-{
- if(!*args)
- return false;
-
- char* cId = extractKeyFromLink((char*)args,"Hgameobject");
- if(!cId)
- return false;
-
- uint32 lowguid = atoi(cId);
- if(!lowguid)
- return false;
-
- GameObject* obj = NULL;
-
- // by DB guid
- if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
- obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
-
- if(!obj)
- {
- PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- // Activate
- obj->SetLootState(GO_READY);
- obj->UseDoorOrButton(10000);
-
- PSendSysMessage("Object activated!");
-
- return true;
-}
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "Item.h"
+#include "GameObject.h"
+#include "Opcodes.h"
+#include "Chat.h"
+#include "ObjectAccessor.h"
+#include "MapManager.h"
+#include "Language.h"
+#include "World.h"
+#include "GameEvent.h"
+#include "SpellMgr.h"
+#include "AccountMgr.h"
+#include "GMTicketMgr.h"
+#include "WaypointManager.h"
+#include "Util.h"
+#include <cctype>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include "GlobalEvents.h"
+
+#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
+
+static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
+{
+ LANG_REP_HATED, LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL,
+ LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED, LANG_REP_EXALTED
+};
+
+//mute player for some times
+bool ChatHandler::HandleMuteCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char *charname = strtok((char*)args, " ");
+ if (!charname)
+ return false;
+
+ std::string cname = charname;
+
+ char *timetonotspeak = strtok(NULL, " ");
+ if(!timetonotspeak)
+ return false;
+
+ uint32 notspeaktime = (uint32) atoi(timetonotspeak);
+
+ if(!normalizePlayerName(cname))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
+ if(!guid)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = objmgr.GetPlayer(guid);
+
+ // check security
+ uint32 account_id = 0;
+ uint32 security = 0;
+
+ if (chr)
+ {
+ account_id = chr->GetSession()->GetAccountId();
+ security = chr->GetSession()->GetSecurity();
+ }
+ else
+ {
+ account_id = objmgr.GetPlayerAccountIdByGUID(guid);
+ security = accmgr.GetSecurity(account_id);
+ }
+
+ if(m_session && security >= m_session->GetSecurity())
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ time_t mutetime = time(NULL) + notspeaktime*60;
+
+ if (chr)
+ chr->GetSession()->m_muteTime = mutetime;
+
+ loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
+
+ if(chr)
+ ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
+
+ PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
+
+ return true;
+}
+
+//unmute player
+bool ChatHandler::HandleUnmuteCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char *charname = strtok((char*)args, " ");
+ if (!charname)
+ return false;
+
+ std::string cname = charname;
+
+ if(!normalizePlayerName(cname))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
+ if(!guid)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = objmgr.GetPlayer(guid);
+
+ // check security
+ uint32 account_id = 0;
+ uint32 security = 0;
+
+ if (chr)
+ {
+ account_id = chr->GetSession()->GetAccountId();
+ security = chr->GetSession()->GetSecurity();
+ }
+ else
+ {
+ account_id = objmgr.GetPlayerAccountIdByGUID(guid);
+ security = accmgr.GetSecurity(account_id);
+ }
+
+ if(m_session && security >= m_session->GetSecurity())
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (chr)
+ {
+ if(chr->CanSpeak())
+ {
+ SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ chr->GetSession()->m_muteTime = 0;
+ }
+
+ loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
+
+ if(chr)
+ ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
+
+ PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
+ return true;
+}
+
+bool ChatHandler::HandleTargetObjectCommand(const char* args)
+{
+ Player* pl = m_session->GetPlayer();
+ QueryResult *result;
+ GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
+ if(*args)
+ {
+ int32 id = atoi((char*)args);
+ if(id)
+ result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
+ else
+ {
+ std::string name = args;
+ WorldDatabase.escape_string(name);
+ result = WorldDatabase.PQuery(
+ "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
+ "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
+ pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
+ }
+ }
+ else
+ {
+ std::ostringstream eventFilter;
+ eventFilter << " AND (event IS NULL ";
+ bool initString = true;
+
+ for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
+ {
+ if (initString)
+ {
+ eventFilter << "OR event IN (" <<*itr;
+ initString =false;
+ }
+ else
+ eventFilter << "," << *itr;
+ }
+
+ if (!initString)
+ eventFilter << "))";
+ else
+ eventFilter << ")";
+
+ result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
+ "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
+ "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
+ m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
+ }
+
+ if (!result)
+ {
+ SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
+ return true;
+ }
+
+ Field *fields = result->Fetch();
+ uint32 lowguid = fields[0].GetUInt32();
+ uint32 id = fields[1].GetUInt32();
+ float x = fields[2].GetFloat();
+ float y = fields[3].GetFloat();
+ float z = fields[4].GetFloat();
+ float o = fields[5].GetFloat();
+ int mapid = fields[6].GetUInt16();
+ delete result;
+
+ GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
+
+ if (!goI)
+ {
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
+ return false;
+ }
+
+ GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
+
+ PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
+
+ if(target)
+ {
+ int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
+ if(curRespawnDelay < 0)
+ curRespawnDelay = 0;
+
+ std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
+ std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
+
+ PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
+ }
+ return true;
+}
+
+//teleport to gameobject
+bool ChatHandler::HandleGoObjectCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ Player* _player = m_session->GetPlayer();
+
+ // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if(!cId)
+ return false;
+
+ int32 guid = atoi(cId);
+ if(!guid)
+ return false;
+
+ float x, y, z, ort;
+ int mapid;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(guid))
+ {
+ x = go_data->posX;
+ y = go_data->posY;
+ z = go_data->posZ;
+ ort = go_data->orientation;
+ mapid = go_data->mapid;
+ }
+ else
+ {
+ SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if(_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->m_taxi.ClearTaxiDestinations();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, ort);
+ return true;
+}
+
+bool ChatHandler::HandleGoTriggerCommand(const char* args)
+{
+ Player* _player = m_session->GetPlayer();
+
+ if (!*args)
+ return false;
+
+ char *atId = strtok((char*)args, " ");
+ if (!atId)
+ return false;
+
+ int32 i_atId = atoi(atId);
+
+ if(!i_atId)
+ return false;
+
+ AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
+ if (!at)
+ {
+ PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if(_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->m_taxi.ClearTaxiDestinations();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
+ return true;
+}
+
+bool ChatHandler::HandleGoGraveyardCommand(const char* args)
+{
+ Player* _player = m_session->GetPlayer();
+
+ if (!*args)
+ return false;
+
+ char *gyId = strtok((char*)args, " ");
+ if (!gyId)
+ return false;
+
+ int32 i_gyId = atoi(gyId);
+
+ if(!i_gyId)
+ return false;
+
+ WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
+ if (!gy)
+ {
+ PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if(_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->m_taxi.ClearTaxiDestinations();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
+ return true;
+}
+
+/** \brief Teleport the GM to the specified creature
+ *
+ * .gocreature <GUID> --> TP using creature.guid
+ * .gocreature azuregos --> TP player to the mob with this name
+ * Warning: If there is more than one mob with this name
+ * you will be teleported to the first one that is found.
+ * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
+ * Warning: If there is more than one mob with this "id"
+ * you will be teleported to the first one that is found.
+ */
+//teleport to creature
+bool ChatHandler::HandleGoCreatureCommand(const char* args)
+{
+ if(!*args)
+ return false;
+ Player* _player = m_session->GetPlayer();
+
+ // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
+ char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
+ if (!pParam1)
+ return false;
+
+ std::ostringstream whereClause;
+
+ // User wants to teleport to the NPC's template entry
+ if( strcmp(pParam1, "id") == 0 )
+ {
+ //sLog.outError("DEBUG: ID found");
+
+ // Get the "creature_template.entry"
+ // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
+ char* tail = strtok(NULL,"");
+ if(!tail)
+ return false;
+ char* cId = extractKeyFromLink(tail,"Hcreature_entry");
+ if(!cId)
+ return false;
+
+ int32 tEntry = atoi(cId);
+ //sLog.outError("DEBUG: ID value: %d", tEntry);
+ if(!tEntry)
+ return false;
+
+ whereClause << "WHERE id = '" << tEntry << "'";
+ }
+ else
+ {
+ //sLog.outError("DEBUG: ID *not found*");
+
+ int32 guid = atoi(pParam1);
+
+ // Number is invalid - maybe the user specified the mob's name
+ if(!guid)
+ {
+ std::string name = pParam1;
+ WorldDatabase.escape_string(name);
+ whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
+ }
+ else
+ {
+ whereClause << "WHERE guid = '" << guid << "'";
+ }
+ }
+ //sLog.outError("DEBUG: %s", whereClause.c_str());
+
+ QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
+ if (!result)
+ {
+ SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ if( result->GetRowCount() > 1 )
+ {
+ SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
+ }
+
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ float ort = fields[3].GetFloat();
+ int mapid = fields[4].GetUInt16();
+
+ delete result;
+
+ if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // stop flight if need
+ if(_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->m_taxi.ClearTaxiDestinations();
+ }
+ // save only in non-flight case
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, ort);
+ return true;
+}
+
+bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
+{
+ uint64 guid = m_session->GetPlayer()->GetSelection();
+
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
+ return true;
+}
+
+bool ChatHandler::HandleLookupFactionCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ // Can be NULL at console call
+ Player *target = getSelectedPlayer ();
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr (namepart,wnamepart))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower (wnamepart);
+
+ uint32 counter = 0; // Counter for figure out that we found smth.
+
+ for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
+ if (factionEntry)
+ {
+ FactionState const* repState = NULL;
+ if(target)
+ {
+ FactionStateList::const_iterator repItr = target->m_factions.find (factionEntry->reputationListID);
+ if(repItr != target->m_factions.end())
+ repState = &repItr->second;
+ }
+
+ int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
+ std::string name = factionEntry->name[loc];
+ if(name.empty())
+ continue;
+
+ if (!Utf8FitTo(name, wnamepart))
+ {
+ loc = 0;
+ for(; loc < MAX_LOCALE; ++loc)
+ {
+ if(m_session && loc==m_session->GetSessionDbcLocale())
+ continue;
+
+ name = factionEntry->name[loc];
+ if(name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wnamepart))
+ break;
+ }
+ }
+
+ if(loc < MAX_LOCALE)
+ {
+ // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
+ // or "id - [faction] [no reputation]" format
+ std::ostringstream ss;
+ if (m_session)
+ ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
+ else
+ ss << id << " - " << name << " " << localeNames[loc];
+
+ if (repState) // and then target!=NULL also
+ {
+ ReputationRank rank = target->GetReputationRank(factionEntry);
+ std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
+
+ ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
+
+ if(repState->Flags & FACTION_FLAG_VISIBLE)
+ ss << GetTrinityString(LANG_FACTION_VISIBLE);
+ if(repState->Flags & FACTION_FLAG_AT_WAR)
+ ss << GetTrinityString(LANG_FACTION_ATWAR);
+ if(repState->Flags & FACTION_FLAG_PEACE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
+ if(repState->Flags & FACTION_FLAG_HIDDEN)
+ ss << GetTrinityString(LANG_FACTION_HIDDEN);
+ if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
+ if(repState->Flags & FACTION_FLAG_INACTIVE)
+ ss << GetTrinityString(LANG_FACTION_INACTIVE);
+ }
+ else
+ ss << GetTrinityString(LANG_FACTION_NOREPUTATION);
+
+ SendSysMessage(ss.str().c_str());
+ counter++;
+ }
+ }
+ }
+
+ if (counter == 0) // if counter == 0 then we found nth
+ SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
+ return true;
+}
+
+bool ChatHandler::HandleModifyRepCommand(const char * args)
+{
+ if (!*args) return false;
+
+ Player* target = NULL;
+ target = getSelectedPlayer();
+
+ if(!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
+ if(!factionTxt)
+ return false;
+
+ uint32 factionId = atoi(factionTxt);
+
+ int32 amount = 0;
+ char *rankTxt = strtok(NULL, " ");
+ if (!factionTxt || !rankTxt)
+ return false;
+
+ amount = atoi(rankTxt);
+ if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
+ {
+ std::string rankStr = rankTxt;
+ std::wstring wrankStr;
+ if(!Utf8toWStr(rankStr,wrankStr))
+ return false;
+ wstrToLower( wrankStr );
+
+ int r = 0;
+ amount = -42000;
+ for (; r < MAX_REPUTATION_RANK; ++r)
+ {
+ std::string rank = GetTrinityString(ReputationRankStrIndex[r]);
+ if(rank.empty())
+ continue;
+
+ std::wstring wrank;
+ if(!Utf8toWStr(rank,wrank))
+ continue;
+
+ wstrToLower(wrank);
+
+ if(wrank.substr(0,wrankStr.size())==wrankStr)
+ {
+ char *deltaTxt = strtok(NULL, " ");
+ if (deltaTxt)
+ {
+ int32 delta = atoi(deltaTxt);
+ if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1))
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1));
+ SetSentErrorMessage(true);
+ return false;
+ }
+ amount += delta;
+ }
+ break;
+ }
+ amount += Player::ReputationRank_Length[r];
+ }
+ if (r >= MAX_REPUTATION_RANK)
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
+
+ if (!factionEntry)
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (factionEntry->reputationListID < 0)
+ {
+ PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->SetFactionReputation(factionEntry,amount);
+ PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
+ return true;
+}
+
+bool ChatHandler::HandleNameCommand(const char* args)
+{
+ /* Temp. disabled
+ if(!*args)
+ return false;
+
+ if(strlen((char*)args)>75)
+ {
+ PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
+ return true;
+ }
+
+ for (uint8 i = 0; i < strlen(args); i++)
+ {
+ if(!isalpha(args[i]) && args[i]!=' ')
+ {
+ SendSysMessage(LANG_CHARS_ONLY);
+ return false;
+ }
+ }
+
+ uint64 guid;
+ guid = m_session->GetPlayer()->GetSelection();
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ return true;
+ }
+
+ Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ return true;
+ }
+
+ pCreature->SetName(args);
+ uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
+ pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
+
+ pCreature->SaveToDB();
+ */
+
+ return true;
+}
+
+bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
+{
+ /* Temp. disabled
+
+ if(!*args)
+ args = "";
+
+ if(strlen((char*)args)>75)
+ {
+
+ PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
+ return true;
+ }
+
+ for (uint8 i = 0; i < strlen(args); i++)
+ {
+ if(!isalpha(args[i]) && args[i]!=' ')
+ {
+ SendSysMessage(LANG_CHARS_ONLY);
+ return false;
+ }
+ }
+ uint64 guid;
+ guid = m_session->GetPlayer()->GetSelection();
+ if (guid == 0)
+ {
+ SendSysMessage(LANG_NO_SELECTION);
+ return true;
+ }
+
+ Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ return true;
+ }
+
+ uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
+ pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
+
+ pCreature->SaveToDB();
+ */
+ return true;
+}
+
+//move item to other slot
+bool ChatHandler::HandleItemMoveCommand(const char* args)
+{
+ if(!*args)
+ return false;
+ uint8 srcslot, dstslot;
+
+ char* pParam1 = strtok((char*)args, " ");
+ if (!pParam1)
+ return false;
+
+ char* pParam2 = strtok(NULL, " ");
+ if (!pParam2)
+ return false;
+
+ srcslot = (uint8)atoi(pParam1);
+ dstslot = (uint8)atoi(pParam2);
+
+ if(srcslot==dstslot)
+ return true;
+
+ if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
+ return false;
+
+ if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
+ return false;
+
+ uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
+ uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
+
+ m_session->GetPlayer()->SwapItem( src, dst );
+
+ return true;
+}
+
+//add spawn of creature
+bool ChatHandler::HandleNpcAddCommand(const char* args)
+{
+ if(!*args)
+ return false;
+ char* charID = strtok((char*)args, " ");
+ if (!charID)
+ return false;
+
+ char* team = strtok(NULL, " ");
+ int32 teamval = 0;
+ if (team) { teamval = atoi(team); }
+ if (teamval < 0) { teamval = 0; }
+
+ uint32 id = atoi(charID);
+
+ Player *chr = m_session->GetPlayer();
+ float x = chr->GetPositionX();
+ float y = chr->GetPositionY();
+ float z = chr->GetPositionZ();
+ float o = chr->GetOrientation();
+ Map *map = chr->GetMap();
+
+ Creature* pCreature = new Creature;
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
+ {
+ delete pCreature;
+ return false;
+ }
+
+ pCreature->Relocate(x,y,z,o);
+
+ if(!pCreature->IsPositionValid())
+ {
+ sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ delete pCreature;
+ return false;
+ }
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+
+ uint32 db_guid = pCreature->GetDBTableGUIDLow();
+
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ pCreature->LoadFromDB(db_guid, map);
+
+ map->Add(pCreature);
+ objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
+ return true;
+}
+
+bool ChatHandler::HandleNpcDeleteCommand(const char* args)
+{
+ Creature* unit = NULL;
+
+ if(*args)
+ {
+ // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hcreature");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if(!lowguid)
+ return false;
+
+ if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
+ unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
+ }
+ else
+ unit = getSelectedCreature();
+
+ if(!unit || unit->isPet() || unit->isTotem())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Delete the creature
+ unit->CombatStop();
+ unit->DeleteFromDB();
+ unit->CleanupsBeforeDelete();
+ unit->AddObjectToRemoveList();
+
+ SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
+
+ return true;
+}
+
+//delete object by selection or guid
+bool ChatHandler::HandleDelObjectCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if(!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if(!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 owner_guid = obj->GetOwnerGUID();
+ if(owner_guid)
+ {
+ Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
+ if(!owner && !IS_PLAYER_GUID(owner_guid))
+ {
+ PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ owner->RemoveGameObject(obj,false);
+ }
+
+ obj->SetRespawnTime(0); // not save respawn time
+ obj->Delete();
+ obj->DeleteFromDB();
+
+ PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
+
+ return true;
+}
+
+//turn selected object
+bool ChatHandler::HandleTurnObjectCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if(!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if(!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* po = strtok(NULL, " ");
+ float o;
+
+ if (po)
+ {
+ o = (float)atof(po);
+ }
+ else
+ {
+ Player *chr = m_session->GetPlayer();
+ o = chr->GetOrientation();
+ }
+
+ float rot2 = sin(o/2);
+ float rot3 = cos(o/2);
+
+ Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ map->Remove(obj,false);
+
+ obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
+
+ obj->SetFloatValue(GAMEOBJECT_FACING, o);
+ obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
+ obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
+
+ map->Add(obj);
+
+ obj->SaveToDB();
+ obj->Refresh();
+
+ PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o);
+
+ return true;
+}
+
+//move selected creature
+bool ChatHandler::HandleNpcMoveCommand(const char* args)
+{
+ uint32 lowguid = 0;
+
+ Creature* pCreature = getSelectedCreature();
+
+ if(!pCreature)
+ {
+ // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hcreature");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+
+ /* FIXME: impossibel without entry
+ if(lowguid)
+ pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
+ */
+
+ // Attempting creature load from DB data
+ if(!pCreature)
+ {
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 map_id = data->mapid;
+
+ if(m_session->GetPlayer()->GetMapId()!=map_id)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+ }
+ else
+ {
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+
+ float x = m_session->GetPlayer()->GetPositionX();
+ float y = m_session->GetPlayer()->GetPositionY();
+ float z = m_session->GetPlayer()->GetPositionZ();
+ float o = m_session->GetPlayer()->GetOrientation();
+
+ if (pCreature)
+ {
+ if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
+ {
+ const_cast<CreatureData*>(data)->posX = x;
+ const_cast<CreatureData*>(data)->posY = y;
+ const_cast<CreatureData*>(data)->posZ = z;
+ const_cast<CreatureData*>(data)->orientation = o;
+ }
+ MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
+ pCreature->GetMotionMaster()->Initialize();
+ if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+ }
+
+ WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
+ PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
+ return true;
+}
+
+//move selected object
+bool ChatHandler::HandleMoveObjectCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if(!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if(!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* px = strtok(NULL, " ");
+ char* py = strtok(NULL, " ");
+ char* pz = strtok(NULL, " ");
+
+ if (!px)
+ {
+ Player *chr = m_session->GetPlayer();
+
+ Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ map->Remove(obj,false);
+
+ obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
+ obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
+ obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
+ obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
+
+ map->Add(obj);
+ }
+ else
+ {
+ if(!py || !pz)
+ return false;
+
+ float x = (float)atof(px);
+ float y = (float)atof(py);
+ float z = (float)atof(pz);
+
+ if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
+ {
+ PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ map->Remove(obj,false);
+
+ obj->Relocate(x, y, z, obj->GetOrientation());
+ obj->SetFloatValue(GAMEOBJECT_POS_X, x);
+ obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
+ obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
+
+ map->Add(obj);
+ }
+
+ obj->SaveToDB();
+ obj->Refresh();
+
+ PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
+
+ return true;
+}
+
+//demorph player or unit
+bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
+{
+ Unit *target = getSelectedUnit();
+ if(!target)
+ target = m_session->GetPlayer();
+
+ target->DeMorph();
+
+ return true;
+}
+
+//add item in vendorlist
+bool ChatHandler::HandleAddVendorItemCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* pitem = extractKeyFromLink((char*)args,"Hitem");
+ if (!pitem)
+ {
+ SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 itemId = atol(pitem);
+
+ char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
+ uint32 maxcount = 0;
+ if (fmaxcount)
+ maxcount = atol(fmaxcount);
+
+ char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
+ uint32 incrtime = 0;
+ if (fincrtime)
+ incrtime = atol(fincrtime);
+
+ char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
+ uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
+
+ Creature* vendor = getSelectedCreature();
+
+ uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
+
+ if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
+ {
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
+
+ ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
+
+ PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
+ return true;
+}
+
+//del item from vendor list
+bool ChatHandler::HandleDelVendorItemCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Creature* vendor = getSelectedCreature();
+ if (!vendor || !vendor->isVendor())
+ {
+ SendSysMessage(LANG_COMMAND_VENDORSELECTION);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* pitem = extractKeyFromLink((char*)args,"Hitem");
+ if (!pitem)
+ {
+ SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ uint32 itemId = atol(pitem);
+
+
+ if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
+ {
+ PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
+
+ PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
+ return true;
+}
+
+//add move for creature
+bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ char* guid_str = strtok((char*)args, " ");
+ char* wait_str = strtok((char*)NULL, " ");
+
+ uint32 lowguid = atoi((char*)guid_str);
+
+ Creature* pCreature = NULL;
+
+ /* FIXME: impossible without entry
+ if(lowguid)
+ pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
+ */
+
+ // attempt check creature existence by DB data
+ if(!pCreature)
+ {
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ // obtain real GUID for DB operations
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+
+ int wait = wait_str ? atoi(wait_str) : 0;
+
+ if(wait < 0)
+ wait = 0;
+
+ Player* player = m_session->GetPlayer();
+
+ WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
+
+ // update movement type
+ WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
+ if(pCreature)
+ {
+ pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+ pCreature->GetMotionMaster()->Initialize();
+ if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+ pCreature->SaveToDB();
+ }
+
+ SendSysMessage(LANG_WAYPOINT_ADDED);
+
+ return true;
+}
+
+/**
+ * Set the movement type for an NPC.<br/>
+ * <br/>
+ * Valid movement types are:
+ * <ul>
+ * <li> stay - NPC wont move </li>
+ * <li> random - NPC will move randomly according to the spawndist </li>
+ * <li> way - NPC will move with given waypoints set </li>
+ * </ul>
+ * additional parameter: NODEL - so no waypoints are deleted, if you
+ * change the movement type
+ */
+bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ // 3 arguments:
+ // GUID (optional - you can also select the creature)
+ // stay|random|way (determines the kind of movement)
+ // NODEL (optional - tells the system NOT to delete any waypoints)
+ // this is very handy if you want to do waypoints, that are
+ // later switched on/off according to special events (like escort
+ // quests, etc)
+ char* guid_str = strtok((char*)args, " ");
+ char* type_str = strtok((char*)NULL, " ");
+ char* dontdel_str = strtok((char*)NULL, " ");
+
+ bool doNotDelete = false;
+
+ if(!guid_str)
+ return false;
+
+ uint32 lowguid = 0;
+ Creature* pCreature = NULL;
+
+ if( dontdel_str )
+ {
+ //sLog.outError("DEBUG: All 3 params are set");
+
+ // All 3 params are set
+ // GUID
+ // type
+ // doNotDEL
+ if( stricmp( dontdel_str, "NODEL" ) == 0 )
+ {
+ //sLog.outError("DEBUG: doNotDelete = true;");
+ doNotDelete = true;
+ }
+ }
+ else
+ {
+ // Only 2 params - but maybe NODEL is set
+ if( type_str )
+ {
+ sLog.outError("DEBUG: Only 2 params ");
+ if( stricmp( type_str, "NODEL" ) == 0 )
+ {
+ //sLog.outError("DEBUG: type_str, NODEL ");
+ doNotDelete = true;
+ type_str = NULL;
+ }
+ }
+ }
+
+ if(!type_str) // case .setmovetype $move_type (with selected creature)
+ {
+ type_str = guid_str;
+ pCreature = getSelectedCreature();
+ if(!pCreature || pCreature->isPet())
+ return false;
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+ else // case .setmovetype #creature_guid $move_type (with selected creature)
+ {
+ lowguid = atoi((char*)guid_str);
+
+ /* impossible without entry
+ if(lowguid)
+ pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
+ */
+
+ // attempt check creature existence by DB data
+ if(!pCreature)
+ {
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ lowguid = pCreature->GetDBTableGUIDLow();
+ }
+ }
+
+ // now lowguid is low guid really existed creature
+ // and pCreature point (maybe) to this creature or NULL
+
+ MovementGeneratorType move_type;
+
+ std::string type = type_str;
+
+ if(type == "stay")
+ move_type = IDLE_MOTION_TYPE;
+ else if(type == "random")
+ move_type = RANDOM_MOTION_TYPE;
+ else if(type == "way")
+ move_type = WAYPOINT_MOTION_TYPE;
+ else
+ return false;
+
+ // update movement type
+ if(doNotDelete == false)
+ WaypointMgr.DeletePath(lowguid);
+
+ if(pCreature)
+ {
+ pCreature->SetDefaultMovementType(move_type);
+ pCreature->GetMotionMaster()->Initialize();
+ if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+ pCreature->SaveToDB();
+ }
+ if( doNotDelete == false )
+ {
+ PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
+ }
+ else
+ {
+ PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
+ }
+
+ return true;
+} // HandleNpcSetMoveTypeCommand
+
+//change level of creature or pet
+bool ChatHandler::HandleChangeLevelCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint8 lvl = (uint8) atoi((char*)args);
+ if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* pCreature = getSelectedCreature();
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(pCreature->isPet())
+ {
+ ((Pet*)pCreature)->GivePetLevel(lvl);
+ }
+ else
+ {
+ pCreature->SetMaxHealth( 100 + 30*lvl);
+ pCreature->SetHealth( 100 + 30*lvl);
+ pCreature->SetLevel( lvl);
+ pCreature->SaveToDB();
+ }
+
+ return true;
+}
+
+//set npcflag of creature
+bool ChatHandler::HandleNpcFlagCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 npcFlags = (uint32) atoi((char*)args);
+
+ Creature* pCreature = getSelectedCreature();
+
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
+
+ WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
+
+ SendSysMessage(LANG_VALUE_SAVED_REJOIN);
+
+ return true;
+}
+
+//set model of creature
+bool ChatHandler::HandleNpcSetModelCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 displayId = (uint32) atoi((char*)args);
+
+ Creature *pCreature = getSelectedCreature();
+
+ if(!pCreature || pCreature->isPet())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetDisplayId(displayId);
+ pCreature->SetNativeDisplayId(displayId);
+
+ pCreature->SaveToDB();
+
+ return true;
+}
+
+//morph creature or player
+bool ChatHandler::HandleMorphCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint16 display_id = (uint16)atoi((char*)args);
+
+ Unit *target = getSelectedUnit();
+ if(!target)
+ target = m_session->GetPlayer();
+
+ target->SetDisplayId(display_id);
+
+ return true;
+}
+
+//set faction of creature
+bool ChatHandler::HandleNpcFactionIdCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 factionId = (uint32) atoi((char*)args);
+
+ if (!sFactionTemplateStore.LookupEntry(factionId))
+ {
+ PSendSysMessage(LANG_WRONG_FACTION, factionId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* pCreature = getSelectedCreature();
+
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->setFaction(factionId);
+
+ // faction is set in creature_template - not inside creature
+
+ // update in memory
+ if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
+ {
+ const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
+ const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
+ }
+
+ // and DB
+ WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
+
+ return true;
+}
+
+//kick player
+bool ChatHandler::HandleKickPlayerCommand(const char *args)
+{
+ char* kickName = strtok((char*)args, " ");
+ if (!kickName)
+ {
+ Player* player = getSelectedPlayer();
+
+ if(!player)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(player==m_session->GetPlayer())
+ {
+ SendSysMessage(LANG_COMMAND_KICKSELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ player->GetSession()->KickPlayer();
+ }
+ else
+ {
+ std::string name = kickName;
+ if(!normalizePlayerName(name))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(m_session && name==m_session->GetPlayer()->GetName())
+ {
+ SendSysMessage(LANG_COMMAND_KICKSELF);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(sWorld.KickPlayer(name))
+ {
+ PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
+ }
+ else
+ PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
+ }
+
+ return true;
+}
+
+//show info of player
+bool ChatHandler::HandlePInfoCommand(const char* args)
+{
+ Player* target = NULL;
+ uint64 targetGUID = 0;
+
+ char* px = strtok((char*)args, " ");
+ char* py = NULL;
+
+ std::string name;
+
+ if (px)
+ {
+ name = px;
+
+ if(name.empty())
+ return false;
+
+ if(!normalizePlayerName(name))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target = objmgr.GetPlayer(name.c_str());
+ if (target)
+ py = strtok(NULL, " ");
+ else
+ {
+ targetGUID = objmgr.GetPlayerGUIDByName(name);
+ if(targetGUID)
+ py = strtok(NULL, " ");
+ else
+ py = px;
+ }
+ }
+
+ if(!target && !targetGUID)
+ {
+ target = getSelectedPlayer();
+ }
+
+ if(!target && !targetGUID)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 accId = 0;
+ uint32 money = 0;
+ uint32 total_player_time = 0;
+ uint32 level = 0;
+ uint32 latency = 0;
+
+ // get additional information from Player object
+ if(target)
+ {
+ targetGUID = target->GetGUID();
+ name = target->GetName(); // re-read for case getSelectedPlayer() target
+ accId = target->GetSession()->GetAccountId();
+ money = target->GetMoney();
+ total_player_time = target->GetTotalPlayedTime();
+ level = target->getLevel();
+ latency = target->GetSession()->GetLatency();
+ }
+ // get additional information from DB
+ else
+ {
+ QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));
+ if (!result)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ Field *fields = result->Fetch();
+ total_player_time = fields[0].GetUInt32();
+ delete result;
+
+ Tokens data;
+ if (!Player::LoadValuesArrayFromDB(data,targetGUID))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
+ level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
+ accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
+ }
+
+ std::string username = GetTrinityString(LANG_ERROR);
+ std::string last_ip = GetTrinityString(LANG_ERROR);
+ uint32 security = 0;
+ std::string last_login = GetTrinityString(LANG_ERROR);
+
+ QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
+ if(result)
+ {
+ Field* fields = result->Fetch();
+ username = fields[0].GetCppString();
+ security = fields[1].GetUInt32();
+
+ if(!m_session || m_session->GetSecurity() >= security)
+ {
+ last_ip = fields[2].GetCppString();
+ last_login = fields[3].GetCppString();
+ }
+ else
+ {
+ last_ip = "-";
+ last_login = "-";
+ }
+
+ delete result;
+ }
+
+ PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
+
+ std::string timeStr = secsToTimeString(total_player_time,true,true);
+ uint32 gold = money /GOLD;
+ uint32 silv = (money % GOLD) / SILVER;
+ uint32 copp = (money % GOLD) % SILVER;
+ PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
+
+ if ( py && strncmp(py, "rep", 3) == 0 )
+ {
+ if(!target)
+ {
+ // rep option not implemented for offline case
+ SendSysMessage(LANG_PINFO_NO_REP);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* FactionName;
+ for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
+ if (factionEntry)
+ FactionName = factionEntry->name[m_session->GetSessionDbcLocale()];
+ else
+ FactionName = "#Not found#";
+ ReputationRank rank = target->GetReputationRank(factionEntry);
+ std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
+ std::ostringstream ss;
+ ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
+
+ if(itr->second.Flags & FACTION_FLAG_VISIBLE)
+ ss << GetTrinityString(LANG_FACTION_VISIBLE);
+ if(itr->second.Flags & FACTION_FLAG_AT_WAR)
+ ss << GetTrinityString(LANG_FACTION_ATWAR);
+ if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
+ if(itr->second.Flags & FACTION_FLAG_HIDDEN)
+ ss << GetTrinityString(LANG_FACTION_HIDDEN);
+ if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
+ ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
+ if(itr->second.Flags & FACTION_FLAG_INACTIVE)
+ ss << GetTrinityString(LANG_FACTION_INACTIVE);
+
+ SendSysMessage(ss.str().c_str());
+ }
+ }
+ return true;
+}
+
+//show tickets
+void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
+{
+ std::string name;
+ if(!objmgr.GetPlayerNameByGUID(guid,name))
+ name = GetTrinityString(LANG_UNKNOWN);
+
+ PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text);
+}
+
+//ticket commands
+bool ChatHandler::HandleTicketCommand(const char* args)
+{
+ char* px = strtok((char*)args, " ");
+
+ // ticket<end>
+ if (!px)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ size_t count = ticketmgr.GetTicketCount();
+
+ bool accept = m_session->GetPlayer()->isAcceptTickets();
+
+ PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ? GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF));
+ return true;
+ }
+
+ // ticket on
+ if(strncmp(px,"on",3) == 0)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SetAcceptTicket(true);
+ SendSysMessage(LANG_COMMAND_TICKETON);
+ return true;
+ }
+
+ // ticket off
+ if(strncmp(px,"off",4) == 0)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SetAcceptTicket(false);
+ SendSysMessage(LANG_COMMAND_TICKETOFF);
+ return true;
+ }
+
+ // ticket #num
+ int num = atoi(px);
+ if(num > 0)
+ {
+ QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
+
+ if(!result)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Field* fields = result->Fetch();
+
+ uint32 guid = fields[0].GetUInt32();
+ char const* text = fields[1].GetString();
+ char const* time = fields[2].GetString();
+
+ ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
+ delete result;
+ return true;
+ }
+
+ std::string name = px;
+
+ if(!normalizePlayerName(name))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
+
+ if(!guid)
+ return false;
+
+ // ticket $char_name
+ GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid));
+ if(!ticket)
+ return false;
+
+ std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
+
+ ShowTicket(guid, ticket->GetText(), time.c_str());
+
+ return true;
+}
+
+//dell all tickets
+bool ChatHandler::HandleDelTicketCommand(const char *args)
+{
+ char* px = strtok((char*)args, " ");
+ if (!px)
+ return false;
+
+ // delticket all
+ if(strncmp(px,"all",4) == 0)
+ {
+ ticketmgr.DeleteAll();
+ SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
+ return true;
+ }
+
+ int num = (uint32)atoi(px);
+
+ // delticket #num
+ if(num > 0)
+ {
+ QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
+ if(!result)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Field* fields = result->Fetch();
+
+ uint32 guid = fields[0].GetUInt32();
+ delete result;
+
+ ticketmgr.Delete(guid);
+
+ //notify player
+ if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
+ {
+ pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
+ PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, pl->GetName());
+ }
+ else
+ PSendSysMessage(LANG_COMMAND_TICKETDEL);
+
+ return true;
+ }
+
+ std::string name = px;
+
+ if(!normalizePlayerName(name))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
+
+ if(!guid)
+ return false;
+
+ // delticket $char_name
+ ticketmgr.Delete(GUID_LOPART(guid));
+
+ // notify players about ticket deleting
+ if(Player* sender = objmgr.GetPlayer(guid))
+ sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
+
+ PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
+ return true;
+}
+
+//set spawn dist of creature
+bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ float option = atof((char*)args);
+ if (option < 0.0f)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ return false;
+ }
+
+ MovementGeneratorType mtype = IDLE_MOTION_TYPE;
+ if (option >0.0f)
+ mtype = RANDOM_MOTION_TYPE;
+
+ Creature *pCreature = getSelectedCreature();
+ uint32 u_guidlow = 0;
+
+ if (pCreature)
+ u_guidlow = pCreature->GetDBTableGUIDLow();
+ else
+ return false;
+
+ pCreature->SetRespawnRadius((float)option);
+ pCreature->SetDefaultMovementType(mtype);
+ pCreature->GetMotionMaster()->Initialize();
+ if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ pCreature->setDeathState(JUST_DIED);
+ pCreature->Respawn();
+ }
+
+ WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
+ PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
+ return true;
+}
+
+bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ char* stime = strtok((char*)args, " ");
+
+ if (!stime)
+ return false;
+
+ int i_stime = atoi((char*)stime);
+
+ if (i_stime < 0)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature *pCreature = getSelectedCreature();
+ uint32 u_guidlow = 0;
+
+ if (pCreature)
+ u_guidlow = pCreature->GetDBTableGUIDLow();
+ else
+ return false;
+
+ WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
+ pCreature->SetRespawnDelay((uint32)i_stime);
+ PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
+
+ return true;
+}
+
+/**
+ * Add a waypoint to a creature.
+ *
+ * The user can either select an npc or provide its GUID.
+ *
+ * The user can even select a visual waypoint - then the new waypoint
+ * is placed *after* the selected one - this makes insertion of new
+ * waypoints possible.
+ *
+ * eg:
+ * .wp add 12345
+ * -> adds a waypoint to the npc with the GUID 12345
+ *
+ * .wp add
+ * -> adds a waypoint to the currently selected creature
+ *
+ *
+ * @param args if the user did not provide a GUID, it is NULL
+ *
+ * @return true - command did succeed, false - something went wrong
+ */
+bool ChatHandler::HandleWpAddCommand(const char* args)
+{
+ sLog.outDebug("DEBUG: HandleWpAddCommand");
+
+ // optional
+ char* guid_str = NULL;
+
+ if(*args)
+ {
+ guid_str = strtok((char*)args, " ");
+ }
+
+ uint32 lowguid = 0;
+ uint32 point = 0;
+ Creature* target = getSelectedCreature();
+ // Did player provide a GUID?
+ if (!guid_str)
+ {
+ sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
+
+ // No GUID provided
+ // -> Player must have selected a creature
+
+ if(!target || target->isPet())
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ if (target->GetEntry() == VISUAL_WAYPOINT )
+ {
+ sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
+
+ QueryResult *result =
+ WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
+ target->GetGUIDLow() );
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
+ // User selected a visual spawnpoint -> get the NPC
+ // Select NPC GUID
+ // Since we compare float values, we have to deal with
+ // some difficulties.
+ // Here we search for all waypoints that only differ in one from 1 thousand
+ // (0.001) - There is no other way to compare C++ floats with mySQL floats
+ // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
+ const char* maxDIFF = "0.01";
+ result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
+ target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ do
+ {
+ Field *fields = result->Fetch();
+ lowguid = fields[0].GetUInt32();
+ point = fields[1].GetUInt32();
+ }while( result->NextRow() );
+ delete result;
+
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
+ if(!target)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ lowguid = target->GetDBTableGUIDLow();
+ }
+ }
+ else
+ {
+ sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
+
+ // GUID provided
+ // Warn if player also selected a creature
+ // -> Creature selection is ignored <-
+ if(target)
+ {
+ SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
+ }
+ lowguid = atoi((char*)guid_str);
+
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
+ if(!target || target->isPet())
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ // lowguid -> GUID of the NPC
+ // point -> number of the waypoint (if not 0)
+ sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
+
+ sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
+
+ Player* player = m_session->GetPlayer();
+ WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
+
+ // update movement type
+ if(target)
+ {
+ target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+ target->GetMotionMaster()->Initialize();
+ if(target->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ target->setDeathState(JUST_DIED);
+ target->Respawn();
+ }
+ target->SaveToDB();
+ }
+ else
+ WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
+
+ PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
+
+ return true;
+} // HandleWpAddCommand
+
+/**
+ * .wp modify emote | spell | text | del | move | add
+ *
+ * add -> add a WP after the selected visual waypoint
+ * User must select a visual waypoint and then issue ".wp modify add"
+ *
+ * emote <emoteID>
+ * User has selected a visual waypoint before.
+ * <emoteID> is added to this waypoint. Everytime the
+ * NPC comes to this waypoint, the emote is called.
+ *
+ * emote <GUID> <WPNUM> <emoteID>
+ * User has not selected visual waypoint before.
+ * For the waypoint <WPNUM> for the NPC with <GUID>
+ * an emote <emoteID> is added.
+ * Everytime the NPC comes to this waypoint, the emote is called.
+ *
+ *
+ * info <GUID> <WPNUM> -> User did not select a visual waypoint and
+ */
+bool ChatHandler::HandleWpModifyCommand(const char* args)
+{
+ sLog.outDebug("DEBUG: HandleWpModifyCommand");
+
+ if(!*args)
+ return false;
+
+ // first arg: add del text emote spell waittime move
+ char* show_str = strtok((char*)args, " ");
+ if (!show_str)
+ {
+ return false;
+ }
+
+ std::string show = show_str;
+ // Check
+ // Remember: "show" must also be the name of a column!
+ if( (show != "emote") && (show != "spell") && (show != "textid1") && (show != "textid2")
+ && (show != "textid3") && (show != "textid4") && (show != "textid5")
+ && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
+ && (show != "model1") && (show != "model2") && (show != "orientation"))
+ {
+ return false;
+ }
+
+ // Next arg is: <GUID> <WPNUM> <ARGUMENT>
+
+ // Did user provide a GUID
+ // or did the user select a creature?
+ // -> variable lowguid is filled with the GUID of the NPC
+ uint32 lowguid = 0;
+ uint32 point = 0;
+ uint32 wpGuid = 0;
+ Creature* target = getSelectedCreature();
+
+ if(target)
+ {
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
+
+ // Did the user select a visual spawnpoint?
+ if (target->GetEntry() != VISUAL_WAYPOINT )
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ wpGuid = target->GetGUIDLow();
+
+ // The visual waypoint
+ QueryResult *result =
+ WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
+ target->GetGUIDLow() );
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
+
+ Field *fields = result->Fetch();
+ lowguid = fields[0].GetUInt32();
+ point = fields[1].GetUInt32();
+
+ // Cleanup memory
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
+ delete result;
+ }
+ else
+ {
+ // User did provide <GUID> <WPNUM>
+
+ char* guid_str = strtok((char*)NULL, " ");
+ if( !guid_str )
+ {
+ SendSysMessage(LANG_WAYPOINT_NOGUID);
+ return false;
+ }
+ lowguid = atoi((char*)guid_str);
+
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
+
+ char* point_str = strtok((char*)NULL, " ");
+ if( !point_str )
+ {
+ SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
+ return false;
+ }
+ point = atoi((char*)point_str);
+
+ PSendSysMessage("DEBUG: wpNumber provided: %d", point);
+
+ // Now we need the GUID of the visual waypoint
+ // -> "del", "move", "add" command
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
+ if (!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Field *fields = result->Fetch();
+ wpGuid = fields[0].GetUInt32();
+
+ // Free memory
+ delete result;
+ }
+
+ char* arg_str = NULL;
+ // Check for argument
+ if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
+ {
+ // Text is enclosed in "<>", all other arguments not
+ if( show.find("text") != std::string::npos )
+ arg_str = strtok((char*)NULL, "<>");
+ else
+ arg_str = strtok((char*)NULL, " ");
+
+ if( !arg_str)
+ {
+ PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
+ return false;
+ }
+ }
+
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
+
+ // wpGuid -> GUID of the waypoint creature
+ // lowguid -> GUID of the NPC
+ // point -> waypoint number
+
+ // Special functions:
+ // add - move - del -> no args commands
+ // Add a waypoint after the selected visual
+ if(show == "add" && target)
+ {
+ PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
+
+ // Get the creature for which we read the waypoint
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
+
+ if( !npcCreature )
+ {
+ PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
+
+ // What to do:
+ // Add the visual spawnpoint (DB only)
+ // Adjust the waypoints
+ // Respawn the owner of the waypoints
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
+
+ Player* chr = m_session->GetPlayer();
+ Map *map = chr->GetMap();
+
+ if(npcCreature)
+ {
+ npcCreature->GetMotionMaster()->Initialize();
+ if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ npcCreature->setDeathState(JUST_DIED);
+ npcCreature->Respawn();
+ }
+ }
+
+ // create the waypoint creature
+ wpGuid = 0;
+ Creature* wpCreature = new Creature;
+ if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
+ delete wpCreature;
+ }
+ else
+ {
+ wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
+
+ if(!wpCreature->IsPositionValid())
+ {
+ sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
+ delete wpCreature;
+ }
+ else
+ {
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
+ map->Add(wpCreature);
+ wpGuid = wpCreature->GetGUIDLow();
+ }
+ }
+
+ WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
+
+ if(!wpGuid)
+ return false;
+
+ PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
+ return true;
+ } // add
+
+ if(show == "del" && target)
+ {
+ PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
+
+ // Get the creature for which we read the waypoint
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
+
+ // wpCreature
+ Creature* wpCreature = NULL;
+ if( wpGuid != 0 )
+ {
+ wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature->DeleteFromDB();
+ wpCreature->CleanupsBeforeDelete();
+ wpCreature->AddObjectToRemoveList();
+ }
+
+ // What to do:
+ // Remove the visual spawnpoint
+ // Adjust the waypoints
+ // Respawn the owner of the waypoints
+
+ WaypointMgr.DeleteNode(lowguid, point);
+
+ if(npcCreature)
+ {
+ // Any waypoints left?
+ QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
+ if(!result2)
+ {
+ npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
+ }
+ else
+ {
+ npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+ delete result2;
+ }
+ npcCreature->GetMotionMaster()->Initialize();
+ if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ npcCreature->setDeathState(JUST_DIED);
+ npcCreature->Respawn();
+ }
+ npcCreature->SaveToDB();
+ }
+
+ PSendSysMessage(LANG_WAYPOINT_REMOVED);
+ return true;
+ } // del
+
+ if(show == "move" && target)
+ {
+ PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
+
+ Player *chr = m_session->GetPlayer();
+ Map *map = chr->GetMap();
+ {
+ // Get the creature for which we read the waypoint
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
+
+ // wpCreature
+ Creature* wpCreature = NULL;
+ // What to do:
+ // Move the visual spawnpoint
+ // Respawn the owner of the waypoints
+ if( wpGuid != 0 )
+ {
+ wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature->DeleteFromDB();
+ wpCreature->CleanupsBeforeDelete();
+ wpCreature->AddObjectToRemoveList();
+ // re-create
+ Creature* wpCreature2 = new Creature;
+ if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
+ delete wpCreature2;
+ return false;
+ }
+
+ wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
+
+ if(!wpCreature2->IsPositionValid())
+ {
+ sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());
+ delete wpCreature2;
+ return false;
+ }
+
+ wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
+ map->Add(wpCreature2);
+ //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
+ }
+
+ WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
+
+ if(npcCreature)
+ {
+ npcCreature->GetMotionMaster()->Initialize();
+ if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ npcCreature->setDeathState(JUST_DIED);
+ npcCreature->Respawn();
+ }
+ }
+ PSendSysMessage(LANG_WAYPOINT_CHANGED);
+ }
+ return true;
+ } // move
+
+ // Create creature - npc that has the waypoint
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // set in game textids not supported
+ if( show == "textid1" || show == "textid2" || show == "textid3" ||
+ show == "textid4" || show == "textid5" )
+ {
+ return false;
+ }
+
+ WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
+
+ Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
+ if(npcCreature)
+ {
+ npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+ npcCreature->GetMotionMaster()->Initialize();
+ if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
+ {
+ npcCreature->setDeathState(JUST_DIED);
+ npcCreature->Respawn();
+ }
+ }
+ PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
+
+ return true;
+}
+
+/**
+ * .wp show info | on | off
+ *
+ * info -> User has selected a visual waypoint before
+ *
+ * info <GUID> <WPNUM> -> User did not select a visual waypoint and
+ * provided the GUID of the NPC and the number of
+ * the waypoint.
+ *
+ * on -> User has selected an NPC; all visual waypoints for this
+ * NPC are added to the world
+ *
+ * on <GUID> -> User did not select an NPC - instead the GUID of the
+ * NPC is provided. All visual waypoints for this NPC
+ * are added from the world.
+ *
+ * off -> User has selected an NPC; all visual waypoints for this
+ * NPC are removed from the world.
+ *
+ * on <GUID> -> User did not select an NPC - instead the GUID of the
+ * NPC is provided. All visual waypoints for this NPC
+ * are removed from the world.
+ *
+ *
+ */
+bool ChatHandler::HandleWpShowCommand(const char* args)
+{
+ sLog.outDebug("DEBUG: HandleWpShowCommand");
+
+ if(!*args)
+ return false;
+
+ // first arg: on, off, first, last
+ char* show_str = strtok((char*)args, " ");
+ if (!show_str)
+ {
+ return false;
+ }
+ // second arg: GUID (optional, if a creature is selected)
+ char* guid_str = strtok((char*)NULL, " ");
+ sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
+ //if (!guid_str) {
+ // return false;
+ //}
+
+ // Did user provide a GUID
+ // or did the user select a creature?
+ // -> variable lowguid is filled with the GUID
+ Creature* target = getSelectedCreature();
+ // Did player provide a GUID?
+ if (!guid_str)
+ {
+ sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
+ // No GUID provided
+ // -> Player must have selected a creature
+
+ if(!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
+ // GUID provided
+ // Warn if player also selected a creature
+ // -> Creature selection is ignored <-
+ if(target)
+ {
+ SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
+ }
+
+ uint32 lowguid = atoi((char*)guid_str);
+
+ CreatureData const* data = objmgr.GetCreatureData(lowguid);
+ if(!data)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
+
+ if(!target)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ uint32 lowguid = target->GetDBTableGUIDLow();
+
+ std::string show = show_str;
+ uint32 Maxpoint;
+
+ sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid, show_str);
+
+ // Show info for the selected waypoint
+ if(show == "info")
+ {
+ PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
+
+ // Check if the user did specify a visual waypoint
+ if( target->GetEntry() != VISUAL_WAYPOINT )
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ //PSendSysMessage("wp on, GUID: %u", lowguid);
+
+ //pCreature->GetPositionX();
+
+ QueryResult *result =
+ WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
+ target->GetGUIDLow() );
+ if(!result)
+ {
+ // Since we compare float values, we have to deal with
+ // some difficulties.
+ // Here we search for all waypoints that only differ in one from 1 thousand
+ // (0.001) - There is no other way to compare C++ floats with mySQL floats
+ // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
+ const char* maxDIFF = "0.01";
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
+
+ result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
+ target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 creGUID = fields[0].GetUInt32();
+ uint32 point = fields[1].GetUInt32();
+ int waittime = fields[2].GetUInt32();
+ uint32 emote = fields[3].GetUInt32();
+ uint32 spell = fields[4].GetUInt32();
+ uint32 textid[MAX_WAYPOINT_TEXT];
+ for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
+ textid[i] = fields[5+i].GetUInt32();
+ uint32 model1 = fields[10].GetUInt32();
+ uint32 model2 = fields[11].GetUInt32();
+
+ // Get the creature for which we read the waypoint
+ Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+
+ PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
+ PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
+ PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
+ PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
+ PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
+ PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
+ for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
+ PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, i+1, textid[i], (textid[i] ? GetTrinityString(textid[i]) : ""));
+
+ }while( result->NextRow() );
+ // Cleanup memory
+ delete result;
+ return true;
+ }
+
+ if(show == "on")
+ {
+ PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // Delete all visuals for this NPC
+ QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
+ if(result2)
+ {
+ bool hasError = false;
+ do
+ {
+ Field *fields = result2->Fetch();
+ uint32 wpguid = fields[0].GetUInt32();
+ Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+
+ if(!pCreature)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
+ hasError = true;
+ WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
+ }
+ else
+ {
+ pCreature->DeleteFromDB();
+ pCreature->CleanupsBeforeDelete();
+ pCreature->AddObjectToRemoveList();
+ }
+
+ }while( result2->NextRow() );
+ delete result2;
+ if( hasError )
+ {
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
+ }
+ }
+
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 point = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+
+ uint32 id = VISUAL_WAYPOINT;
+
+ Player *chr = m_session->GetPlayer();
+ Map *map = chr->GetMap();
+ float o = chr->GetOrientation();
+
+ Creature* wpCreature = new Creature;
+ if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
+ delete wpCreature;
+ delete result;
+ return false;
+ }
+
+ wpCreature->Relocate(x, y, z, o);
+
+ if(!wpCreature->IsPositionValid())
+ {
+ sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
+ delete wpCreature;
+ delete result;
+ return false;
+ }
+
+ wpCreature->SetVisibility(VISIBILITY_OFF);
+ sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
+ // set "wpguid" column to the visual waypoint
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
+
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
+ map->Add(wpCreature);
+ //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
+ }while( result->NextRow() );
+
+ // Cleanup memory
+ delete result;
+ return true;
+ }
+
+ if(show == "first")
+ {
+ PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ uint32 id = VISUAL_WAYPOINT;
+
+ Player *chr = m_session->GetPlayer();
+ float o = chr->GetOrientation();
+ Map *map = chr->GetMap();
+
+ Creature* pCreature = new Creature;
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
+ {
+ PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
+ delete pCreature;
+ delete result;
+ return false;
+ }
+
+ pCreature->Relocate(x, y, z, o);
+
+ if(!pCreature->IsPositionValid())
+ {
+ sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ delete pCreature;
+ delete result;
+ return false;
+ }
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
+ map->Add(pCreature);
+ //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
+
+ // Cleanup memory
+ delete result;
+ return true;
+ }
+
+ if(show == "last")
+ {
+ PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
+ if( result )
+ {
+ Maxpoint = (*result)[0].GetUInt32();
+
+ delete result;
+ }
+ else
+ Maxpoint = 0;
+
+ result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ uint32 id = VISUAL_WAYPOINT;
+
+ Player *chr = m_session->GetPlayer();
+ float o = chr->GetOrientation();
+ Map *map = chr->GetMap();
+
+ Creature* pCreature = new Creature;
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
+ delete pCreature;
+ delete result;
+ return false;
+ }
+
+ pCreature->Relocate(x, y, z, o);
+
+ if(!pCreature->IsPositionValid())
+ {
+ sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
+ delete pCreature;
+ delete result;
+ return false;
+ }
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
+ map->Add(pCreature);
+ //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
+ // Cleanup memory
+ delete result;
+ return true;
+ }
+
+ if(show == "off")
+ {
+ QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
+ if(!result)
+ {
+ SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ bool hasError = false;
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+
+ //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
+
+ if(!pCreature)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
+ hasError = true;
+ WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
+ }
+ else
+ {
+ pCreature->DeleteFromDB();
+ pCreature->CleanupsBeforeDelete();
+ pCreature->AddObjectToRemoveList();
+ }
+ }while(result->NextRow());
+ // set "wpguid" column to "empty" - no visual waypoint spawned
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
+
+ if( hasError )
+ {
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
+ PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
+ }
+
+ SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
+ // Cleanup memory
+ delete result;
+
+ return true;
+ }
+
+ PSendSysMessage("DEBUG: wpshow - no valid command found");
+
+ return true;
+} // HandleWpShowCommand
+
+bool ChatHandler::HandleWpExportCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ // Next arg is: <GUID> <ARGUMENT>
+
+ // Did user provide a GUID
+ // or did the user select a creature?
+ // -> variable lowguid is filled with the GUID of the NPC
+ uint32 lowguid = 0;
+ Creature* target = getSelectedCreature();
+ char* arg_str = NULL;
+ if (target)
+ {
+ if (target->GetEntry() != VISUAL_WAYPOINT)
+ lowguid = target->GetGUIDLow();
+ else
+ {
+ QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
+ if (!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
+ return true;
+ }
+ Field *fields = result->Fetch();
+ lowguid = fields[0].GetUInt32();;
+ delete result;
+ }
+
+ arg_str = strtok((char*)args, " ");
+ }
+ else
+ {
+ // user provided <GUID>
+ char* guid_str = strtok((char*)args, " ");
+ if( !guid_str )
+ {
+ SendSysMessage(LANG_WAYPOINT_NOGUID);
+ return false;
+ }
+ lowguid = atoi((char*)guid_str);
+
+ arg_str = strtok((char*)NULL, " ");
+ }
+
+ if( !arg_str)
+ {
+ PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
+ return false;
+ }
+
+ PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
+
+ QueryResult *result = WorldDatabase.PQuery(
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
+
+ if (!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ std::ofstream outfile;
+ outfile.open (arg_str);
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ outfile << "INSERT INTO creature_movement ";
+ outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
+
+ outfile << "( ";
+ outfile << fields[15].GetUInt32(); // id
+ outfile << ", ";
+ outfile << fields[0].GetUInt32(); // point
+ outfile << ", ";
+ outfile << fields[1].GetFloat(); // position_x
+ outfile << ", ";
+ outfile << fields[2].GetFloat(); // position_y
+ outfile << ", ";
+ outfile << fields[3].GetUInt32(); // position_z
+ outfile << ", ";
+ outfile << fields[4].GetUInt32(); // orientation
+ outfile << ", ";
+ outfile << fields[5].GetUInt32(); // model1
+ outfile << ", ";
+ outfile << fields[6].GetUInt32(); // model2
+ outfile << ", ";
+ outfile << fields[7].GetUInt16(); // waittime
+ outfile << ", ";
+ outfile << fields[8].GetUInt32(); // emote
+ outfile << ", ";
+ outfile << fields[9].GetUInt32(); // spell
+ outfile << ", ";
+ outfile << fields[10].GetUInt32(); // textid1
+ outfile << ", ";
+ outfile << fields[11].GetUInt32(); // textid2
+ outfile << ", ";
+ outfile << fields[12].GetUInt32(); // textid3
+ outfile << ", ";
+ outfile << fields[13].GetUInt32(); // textid4
+ outfile << ", ";
+ outfile << fields[14].GetUInt32(); // textid5
+ outfile << ");\n ";
+
+ } while( result->NextRow() );
+ delete result;
+
+ PSendSysMessage(LANG_WAYPOINT_EXPORTED);
+ outfile.close();
+
+ return true;
+}
+
+bool ChatHandler::HandleWpImportCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ char* arg_str = strtok((char*)args, " ");
+ if (!arg_str)
+ return false;
+
+ std::string line;
+ std::ifstream infile (arg_str);
+ if (infile.is_open())
+ {
+ while (! infile.eof() )
+ {
+ getline (infile,line);
+ //cout << line << endl;
+ QueryResult *result = WorldDatabase.Query(line.c_str());
+ delete result;
+ }
+ infile.close();
+ }
+ PSendSysMessage(LANG_WAYPOINT_IMPORTED);
+
+ return true;
+}
+
+//rename characters
+bool ChatHandler::HandleRenameCommand(const char* args)
+{
+ Player* target = NULL;
+ uint64 targetGUID = 0;
+ std::string oldname;
+
+ char* px = strtok((char*)args, " ");
+
+ if(px)
+ {
+ oldname = px;
+
+ if(!normalizePlayerName(oldname))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target = objmgr.GetPlayer(oldname.c_str());
+
+ if (!target)
+ targetGUID = objmgr.GetPlayerGUIDByName(oldname);
+ }
+
+ if(!target && !targetGUID)
+ {
+ target = getSelectedPlayer();
+ }
+
+ if(!target && !targetGUID)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(target)
+ {
+ PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
+ target->SetAtLoginFlag(AT_LOGIN_RENAME);
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
+ }
+ else
+ {
+ PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
+ }
+
+ return true;
+}
+
+//spawn go
+bool ChatHandler::HandleGameObjectCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ char* pParam1 = strtok((char*)args, " ");
+ if (!pParam1)
+ return false;
+
+ uint32 id = atoi((char*)pParam1);
+ if(!id)
+ return false;
+
+ char* spawntimeSecs = strtok(NULL, " ");
+
+ const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
+
+ if (!goI)
+ {
+ PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = m_session->GetPlayer();
+ float x = float(chr->GetPositionX());
+ float y = float(chr->GetPositionY());
+ float z = float(chr->GetPositionZ());
+ float o = float(chr->GetOrientation());
+ Map *map = chr->GetMap();
+
+ float rot2 = sin(o/2);
+ float rot3 = cos(o/2);
+
+ GameObject* pGameObj = new GameObject;
+ uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
+
+ if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
+ {
+ delete pGameObj;
+ return false;
+ }
+
+ if( spawntimeSecs )
+ {
+ uint32 value = atoi((char*)spawntimeSecs);
+ pGameObj->SetRespawnTime(value);
+ //sLog.outDebug("*** spawntimeSecs: %d", value);
+ }
+
+ // fill the gameobject data and save to the db
+ pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+
+ // this will generate a new guid if the object is in an instance
+ if(!pGameObj->LoadFromDB(db_lowGUID, map))
+ {
+ delete pGameObj;
+ return false;
+ }
+
+ sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
+
+ map->Add(pGameObj);
+
+ // TODO: is it really necessary to add both the real and DB table guid here ?
+ objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
+
+ PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
+ return true;
+}
+
+//show animation
+bool ChatHandler::HandleAnimCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 anim_id = atoi((char*)args);
+ m_session->GetPlayer()->HandleEmoteCommand(anim_id);
+ return true;
+}
+
+//change standstate
+bool ChatHandler::HandleStandStateCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 anim_id = atoi((char*)args);
+ m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
+
+ return true;
+}
+
+bool ChatHandler::HandleAddHonorCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ Player *target = getSelectedPlayer();
+ if(!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 amount = (uint32)atoi(args);
+ target->RewardHonor(NULL, 1, amount);
+ return true;
+}
+
+bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
+{
+ Unit *target = getSelectedUnit();
+ if(!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->RewardHonor(target, 1);
+ return true;
+}
+
+bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
+{
+ Player *target = getSelectedPlayer();
+ if(!target)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->UpdateHonorFields();
+ return true;
+}
+
+bool ChatHandler::HandleLookupEventCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ // converting string that we try to find to lower case
+ if(!Utf8toWStr(namepart,wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ uint32 counter = 0;
+
+ GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+
+ for(uint32 id = 0; id < events.size(); ++id )
+ {
+ GameEventData const& eventData = events[id];
+
+ std::string descr = eventData.description;
+ if(descr.empty())
+ continue;
+
+ if (Utf8FitTo(descr, wnamepart))
+ {
+ char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : "";
+
+ if(m_session)
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
+ else
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
+
+ ++counter;
+ }
+ }
+
+ if (counter==0)
+ SendSysMessage(LANG_NOEVENTFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleEventActiveListCommand(const char* args)
+{
+ uint32 counter = 0;
+
+ GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+
+ char const* active = GetTrinityString(LANG_ACTIVE);
+
+ for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
+ {
+ uint32 event_id = *itr;
+ GameEventData const& eventData = events[event_id];
+
+ if(m_session)
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
+ else
+ PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
+
+ ++counter;
+ }
+
+ if (counter==0)
+ SendSysMessage(LANG_NOEVENTFOUND);
+
+ return true;
+}
+
+bool ChatHandler::HandleEventInfoCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameevent");
+ if(!cId)
+ return false;
+
+ uint32 event_id = atoi(cId);
+
+ GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+
+ if(event_id >=events.size())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventData const& eventData = events[event_id];
+ if(!eventData.isValid())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ bool active = activeEvents.find(event_id) != activeEvents.end();
+ char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
+
+ std::string startTimeStr = TimeToTimestampStr(eventData.start);
+ std::string endTimeStr = TimeToTimestampStr(eventData.end);
+
+ uint32 delay = gameeventmgr.NextCheck(event_id);
+ time_t nextTime = time(NULL)+delay;
+ std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
+
+ std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
+ std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
+
+ PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
+ startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
+ nextStr.c_str());
+ return true;
+}
+
+bool ChatHandler::HandleEventStartCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameevent");
+ if(!cId)
+ return false;
+
+ int32 event_id = atoi(cId);
+
+ GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+
+ if(event_id < 1 || event_id >=events.size())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventData const& eventData = events[event_id];
+ if(!eventData.isValid())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+ if(activeEvents.find(event_id) != activeEvents.end())
+ {
+ PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ gameeventmgr.StartEvent(event_id,true);
+ return true;
+}
+
+bool ChatHandler::HandleEventStopCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameevent");
+ if(!cId)
+ return false;
+
+ int32 event_id = atoi(cId);
+
+ GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+
+ if(event_id < 1 || event_id >=events.size())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEventData const& eventData = events[event_id];
+ if(!eventData.isValid())
+ {
+ SendSysMessage(LANG_EVENT_NOT_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
+
+ if(activeEvents.find(event_id) == activeEvents.end())
+ {
+ PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ gameeventmgr.StopEvent(event_id,true);
+ return true;
+}
+
+bool ChatHandler::HandleCombatStopCommand(const char* args)
+{
+ Player *player;
+
+ if(*args)
+ {
+ std::string playername = args;
+
+ if(!normalizePlayerName(playername))
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ player = objmgr.GetPlayer(playername.c_str());
+
+ if(!player)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ player = getSelectedPlayer();
+
+ if (!player)
+ player = m_session->GetPlayer();
+ }
+
+ player->CombatStop();
+ player->getHostilRefManager().deleteReferences();
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
+{
+ uint32 classmask = m_session->GetPlayer()->getClassMask();
+
+ for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
+ if( !skillInfo )
+ continue;
+
+ if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
+ {
+ for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
+ {
+ SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
+ if( !skillLine )
+ continue;
+
+ // skip racial skills
+ if( skillLine->racemask != 0 )
+ continue;
+
+ // skip wrong class skills
+ if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
+ continue;
+
+ if( skillLine->skillId != i || skillLine->forward_spellid )
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
+ if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
+ continue;
+
+ m_session->GetPlayer()->learnSpell(skillLine->spellId);
+ }
+ }
+ }
+
+ SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
+ return true;
+}
+
+bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
+{
+ // Learns all recipes of specified profession and sets skill to max
+ // Example: .learn all_recipes enchanting
+
+ Player* target = getSelectedPlayer();
+ if( !target )
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ return false;
+ }
+
+ if (!*args)
+ return false;
+
+ std::wstring wnamepart;
+
+ if(!Utf8toWStr(args,wnamepart))
+ return false;
+
+ uint32 counter = 0; // Counter for figure out that we found smth.
+
+ // converting string that we try to find to lower case
+ wstrToLower( wnamepart );
+
+ uint32 classmask = m_session->GetPlayer()->getClassMask();
+
+ for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
+ if( !skillInfo )
+ continue;
+
+ if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
+ skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
+ continue;
+
+ int loc = m_session->GetSessionDbcLocale();
+ std::string name = skillInfo->name[loc];
+
+ if(Utf8FitTo(name, wnamepart))
+ {
+ for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
+ {
+ SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
+ if( !skillLine )
+ continue;
+
+ if( skillLine->skillId != i || skillLine->forward_spellid )
+ continue;
+
+ // skip racial skills
+ if( skillLine->racemask != 0 )
+ continue;
+
+ // skip wrong class skills
+ if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
+ if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
+ continue;
+
+ if( !target->HasSpell(spellInfo->Id) )
+ m_session->GetPlayer()->learnSpell(skillLine->spellId);
+ }
+
+ uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
+ target->SetSkill(skillInfo->id, maxLevel, maxLevel);
+ PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
+{
+
+ if (!*args)
+ return false;
+
+ std::string ip = strtok ((char*)args, " ");
+ char* limit_str = strtok (NULL, " ");
+ int32 limit = limit_str ? atoi (limit_str) : -1;
+
+ loginDatabase.escape_string (ip);
+
+ QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
+
+ return LookupPlayerSearchCommand (result,limit);
+}
+
+bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ std::string account = strtok ((char*)args, " ");
+ char* limit_str = strtok (NULL, " ");
+ int32 limit = limit_str ? atoi (limit_str) : -1;
+
+ if (!AccountMgr::normilizeString (account))
+ return false;
+
+ loginDatabase.escape_string (account);
+
+ QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
+
+ return LookupPlayerSearchCommand (result,limit);
+}
+
+bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
+{
+
+ if (!*args)
+ return false;
+
+ std::string email = strtok ((char*)args, " ");
+ char* limit_str = strtok (NULL, " ");
+ int32 limit = limit_str ? atoi (limit_str) : -1;
+
+ loginDatabase.escape_string (email);
+
+ QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
+
+ return LookupPlayerSearchCommand (result,limit);
+}
+
+bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
+{
+ if(!result)
+ {
+ PSendSysMessage(LANG_NO_PLAYERS_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ int i =0;
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 acc_id = fields[0].GetUInt32();
+ std::string acc_name = fields[1].GetCppString();
+
+ QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
+ if(chars)
+ {
+ PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
+
+ uint64 guid = 0;
+ std::string name;
+
+ do
+ {
+ Field* charfields = chars->Fetch();
+ guid = charfields[0].GetUInt64();
+ name = charfields[1].GetCppString();
+
+ PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
+ ++i;
+
+ } while( chars->NextRow() && ( limit == -1 || i < limit ) );
+
+ delete chars;
+ }
+ } while(result->NextRow());
+
+ delete result;
+
+ return true;
+}
+
+/// Triggering corpses expire check in world
+bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
+{
+ CorpsesErase();
+ return true;
+}
+
+bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
+{
+ Player *target = getSelectedPlayer();
+
+ if(!target)
+ {
+ PSendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Repair items
+ target->DurabilityRepairAll(false, 0, false);
+
+ PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName());
+ if(needReportToTarget(target))
+ ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName());
+ return true;
+}
+
+bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creature = getSelectedCreature();
+
+ if(!creature)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Follow player - Using pet's default dist and angle
+ creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+
+ PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
+ return true;
+}
+
+bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creature = getSelectedCreature();
+
+ if(!creature)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (creature->GetMotionMaster()->empty() ||
+ creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
+ {
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ TargetedMovementGenerator<Creature> const* mgen
+ = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
+
+ if(mgen->GetTarget()!=player)
+ {
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // reset movement
+ creature->GetMotionMaster()->MovementExpired(true);
+
+ PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
+ return true;
+}
+
+bool ChatHandler::HandleCreatePetCommand(const char* args)
+{
+ Player *player = m_session->GetPlayer();
+ Creature *creatureTarget = getSelectedCreature();
+
+ if(!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ PSendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creatureTarget->GetEntry());
+ // Creatures with family 0 crashes the server
+ if(cInfo->family == 0)
+ {
+ PSendSysMessage("This creature cannot be tamed. (family id: 0).");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(player->GetPetGUID())
+ {
+ PSendSysMessage("You already have a pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Everything looks OK, create new pet
+ Pet* pet = new Pet(HUNTER_PET);
+
+ if(!pet->CreateBaseAtCreature(creatureTarget))
+ {
+ delete pet;
+ PSendSysMessage("Error 1");
+ return false;
+ }
+
+ creatureTarget->setDeathState(JUST_DIED);
+ creatureTarget->RemoveCorpse();
+ creatureTarget->SetHealth(0); // just for nice GM-mode view
+
+ pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, player->GetGUID());
+ pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
+ pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());
+
+ if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
+ {
+ sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
+ PSendSysMessage("Error 2");
+ return false;
+ }
+
+ // prepare visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
+
+ pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
+ // this enables pet details window (Shift+P)
+ pet->AIM_Initialize();
+ pet->InitPetCreateSpells();
+ pet->SetHealth(pet->GetMaxHealth());
+
+ MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet);
+
+ // visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
+
+ player->SetPet(pet);
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ player->PetSpellInitialize();
+
+ return true;
+}
+
+bool ChatHandler::HandlePetLearnCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ Player *plr = m_session->GetPlayer();
+ Pet *pet = plr->GetPet();
+
+ if(!pet)
+ {
+ PSendSysMessage("You have no pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 spellId = extractSpellIdFromLink((char*)args);
+
+ if(!spellId || !sSpellStore.LookupEntry(spellId))
+ return false;
+
+ // Check if pet already has it
+ if(pet->HasSpell(spellId))
+ {
+ PSendSysMessage("Pet already has spell: %u", spellId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Check if spell is valid
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo))
+ {
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spellId);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pet->learnSpell(spellId);
+
+ PSendSysMessage("Pet has learned spell %u", spellId);
+ return true;
+}
+
+bool ChatHandler::HandlePetUnlearnCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ Player *plr = m_session->GetPlayer();
+ Pet *pet = plr->GetPet();
+
+ if(!pet)
+ {
+ PSendSysMessage("You have no pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 spellId = extractSpellIdFromLink((char*)args);
+
+ if(pet->HasSpell(spellId))
+ pet->removeSpell(spellId);
+ else
+ PSendSysMessage("Pet doesn't have that spell");
+
+ return true;
+}
+
+bool ChatHandler::HandlePetTpCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ Player *plr = m_session->GetPlayer();
+ Pet *pet = plr->GetPet();
+
+ if(!pet)
+ {
+ PSendSysMessage("You have no pet");
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 tp = atol(args);
+
+ pet->SetTP(tp);
+
+ PSendSysMessage("Pet's tp changed to %u", tp);
+ return true;
+}
+
+bool ChatHandler::HandleActivateObjectCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if(!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if(!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Activate
+ obj->SetLootState(GO_READY);
+ obj->UseDoorOrButton(10000);
+
+ PSendSysMessage("Object activated!");
+
+ return true;
+}
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index a2f68a4ce58..1fb799cde6b 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -135,6 +135,7 @@ bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
HandleReloadQuestStartScriptsCommand("a");
HandleReloadSpellScriptsCommand("a");
SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
+ HandleReloadDbScriptStringCommand("a");
return true;
}
@@ -601,6 +602,14 @@ bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
return true;
}
+bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg)
+{
+ sLog.outString( "Re-Loading Script strings from `db_script_string`...");
+ objmgr.LoadDbScriptStrings();
+ SendGlobalSysMessage("DB table `db_script_string` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/)
{
sLog.outString( "Re-Loading Graveyard-zone links...");
@@ -1767,7 +1776,8 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
// search highest talent rank
uint32 spellid = 0;
- for(int rank = 4; rank >= 0; --rank)
+ int rank = 4;
+ for(; rank >= 0; --rank)
{
if(talentInfo->RankID[rank]!=0)
{
@@ -4645,91 +4655,149 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
return true;
}
-bool ChatHandler::HandleShutDownCommand(const char* args)
+bool ChatHandler::HandleServerShutDownCancelCommand(const char* args)
+{
+ sWorld.ShutdownCancel();
+ return true;
+}
+
+bool ChatHandler::HandleServerShutDownCommand(const char* args)
{
if(!*args)
return false;
- if(std::string(args)=="cancel")
- {
- sWorld.ShutdownCancel();
- }
- else
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
+ return false;
+
+ if (exitcode_str)
{
- int32 time = atoi(args);
+ int32 exitcode = atoi (exitcode_str);
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
return false;
- sWorld.ShutdownServ(time);
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
+ return false;
+
+ sWorld.ShutdownServ (time, 0, exitcode);
}
+ else
+ sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
return true;
}
-bool ChatHandler::HandleRestartCommand(const char* args)
+bool ChatHandler::HandleServerRestartCommand(const char* args)
{
if(!*args)
return false;
- if(std::string(args)=="cancel")
- {
- sWorld.ShutdownCancel();
- }
- else
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
+ return false;
+
+ if (exitcode_str)
{
- int32 time = atoi(args);
+ int32 exitcode = atoi (exitcode_str);
+
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
+ return false;
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
return false;
- sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART);
+ sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode);
}
+ else
+ sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
return true;
}
-bool ChatHandler::HandleIdleRestartCommand(const char* args)
+bool ChatHandler::HandleServerIdleRestartCommand(const char* args)
{
if(!*args)
return false;
- if(std::string(args)=="cancel")
- {
- sWorld.ShutdownCancel();
- }
- else
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
+ return false;
+
+ if (exitcode_str)
{
- int32 time = atoi(args);
+ int32 exitcode = atoi (exitcode_str);
+
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
+ return false;
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
return false;
- sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART+SHUTDOWN_MASK_IDLE);
+ sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
}
+ else
+ sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
return true;
}
-bool ChatHandler::HandleIdleShutDownCommand(const char* args)
+bool ChatHandler::HandleServerIdleShutDownCommand(const char* args)
{
if(!*args)
return false;
- if(std::string(args)=="cancel")
- {
- sWorld.ShutdownCancel();
- }
- else
+ char* time_str = strtok ((char*) args, " ");
+ char* exitcode_str = strtok (NULL, "");
+
+ int32 time = atoi (time_str);
+
+ ///- Prevent interpret wrong arg value as 0 secs shutdown time
+ if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0)
+ return false;
+
+ if (exitcode_str)
{
- int32 time = atoi(args);
+ int32 exitcode = atoi (exitcode_str);
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0)
+ // Handle atoi() errors
+ if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
return false;
- sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE);
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitcode < 0 || exitcode > 125)
+ return false;
+
+ sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode);
}
+ else
+ sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
return true;
}
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index d91206bf6d9..6605cc78057 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Mail.h"
@@ -187,18 +187,17 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
return;
}
-
if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION))
{
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
return;
}
- if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
- {
- pl->SendMailResult(0, 0, MAIL_ERR_CANT_SEND_WRAPPED_COD);
- return;
- }
+ if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
+ {
+ pl->SendMailResult(0, 0, MAIL_ERR_CANT_SEND_WRAPPED_COD);
+ return;
+ }
}
}
pl->SendMailResult(0, 0, MAIL_OK);
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index ba72775b5cf..3804560b662 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -1713,7 +1713,7 @@ void InstanceMap::CreateInstanceData(bool load)
InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(GetId());
if (mInstance)
{
- i_script = mInstance->script;
+ i_script_id = mInstance->script_id;
i_data = Script->CreateInstanceData(this);
}
@@ -1730,7 +1730,7 @@ void InstanceMap::CreateInstanceData(bool load)
const char* data = fields[0].GetString();
if(data)
{
- sLog.outDebug("Loading instance data for `%s` with id %u", i_script.c_str(), i_InstanceId);
+ sLog.outDebug("Loading instance data for `%s` with id %u", objmgr.GetScriptName(i_script_id), i_InstanceId);
i_data->Load(data);
}
delete result;
@@ -1738,7 +1738,7 @@ void InstanceMap::CreateInstanceData(bool load)
}
else
{
- sLog.outDebug("New instance data, \"%s\" ,initialized!",i_script.c_str());
+ sLog.outDebug("New instance data, \"%s\" ,initialized!", objmgr.GetScriptName(i_script_id));
i_data->Initialize();
}
}
diff --git a/src/game/Map.h b/src/game/Map.h
index 1765d6d09fa..6e0e9cb37a9 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -105,7 +105,7 @@ struct InstanceTemplate
float startLocY;
float startLocZ;
float startLocO;
- char const* script;
+ uint32 script_id;
};
enum LevelRequirementVsMode
@@ -343,7 +343,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map
void Update(const uint32&);
void CreateInstanceData(bool load);
bool Reset(uint8 method);
- std::string GetScript() { return i_script; }
+ uint32 GetScriptId() { return i_script_id; }
InstanceData* GetInstanceData() { return i_data; }
void PermBindAllPlayers(Player *player);
time_t GetResetTime();
@@ -355,10 +355,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map
bool m_resetAfterUnload;
bool m_unloadWhenEmpty;
InstanceData* i_data;
- std::string i_script;
- // only online players that are inside the instance currently
- // TODO ? - use the grid instead to access the players
- PlayerList i_Players;
+ uint32 i_script_id;
};
class TRINITY_DLL_SPEC BattleGroundMap : public Map
diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index 34aefdff074..26279cb76ec 100644
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -222,7 +222,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
return true;
}
-void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode)
+void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId)
{
Map *m = _GetBaseMap(mapid);
if (m && m->Instanceable())
diff --git a/src/game/MapManager.h b/src/game/MapManager.h
index 44197ccd84a..cba0a86d1a5 100644
--- a/src/game/MapManager.h
+++ b/src/game/MapManager.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_MAPMANAGER_H
@@ -27,6 +27,7 @@
#include "Common.h"
#include "Map.h"
#include "GridStates.h"
+
class Transport;
class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLockable<MapManager, ZThread::Mutex> >
@@ -44,7 +45,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
// only const version for outer users
Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); }
- void DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode);
+ void DeleteInstance(uint32 mapid, uint32 instanceId);
inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const
{
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 43d867d779d..fab835a1f8f 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -1,7361 +1,7505 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "Common.h"
-#include "Database/DatabaseEnv.h"
-#include "Database/SQLStorage.h"
-
-#include "Log.h"
-#include "MapManager.h"
-#include "ObjectMgr.h"
-#include "SpellMgr.h"
-#include "UpdateMask.h"
-#include "World.h"
-#include "WorldSession.h"
-#include "Group.h"
-#include "Guild.h"
-#include "ArenaTeam.h"
-#include "Transports.h"
-#include "ProgressBar.h"
-#include "Policies/SingletonImp.h"
-#include "Language.h"
-#include "GameEvent.h"
-#include "Spell.h"
-#include "Chat.h"
-#include "AccountMgr.h"
-#include "InstanceSaveMgr.h"
-#include "SpellAuras.h"
-#include "Util.h"
-
-INSTANTIATE_SINGLETON_1(ObjectMgr);
-
-ScriptMapMap sQuestEndScripts;
-ScriptMapMap sQuestStartScripts;
-ScriptMapMap sSpellScripts;
-ScriptMapMap sGameObjectScripts;
-ScriptMapMap sEventScripts;
-
-bool normalizePlayerName(std::string& name)
-{
- if(name.empty())
- return false;
-
- wchar_t wstr_buf[MAX_INTERNAL_PLAYER_NAME+1];
- size_t wstr_len = MAX_INTERNAL_PLAYER_NAME;
-
- if(!Utf8toWStr(name,&wstr_buf[0],wstr_len))
- return false;
-
- wstr_buf[0] = wcharToUpper(wstr_buf[0]);
- for(size_t i = 1; i < wstr_len; ++i)
- wstr_buf[i] = wcharToLower(wstr_buf[i]);
-
- if(!WStrToUtf8(wstr_buf,wstr_len,name))
- return false;
-
- return true;
-}
-
-LanguageDesc lang_description[LANGUAGES_COUNT] =
-{
- { LANG_ADDON, 0, 0 },
- { LANG_UNIVERSAL, 0, 0 },
- { LANG_ORCISH, 669, SKILL_LANG_ORCISH },
- { LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN },
- { LANG_TAURAHE, 670, SKILL_LANG_TAURAHE },
- { LANG_DWARVISH, 672, SKILL_LANG_DWARVEN },
- { LANG_COMMON, 668, SKILL_LANG_COMMON },
- { LANG_DEMONIC, 815, SKILL_LANG_DEMON_TONGUE },
- { LANG_TITAN, 816, SKILL_LANG_TITAN },
- { LANG_THALASSIAN, 813, SKILL_LANG_THALASSIAN },
- { LANG_DRACONIC, 814, SKILL_LANG_DRACONIC },
- { LANG_KALIMAG, 817, SKILL_LANG_OLD_TONGUE },
- { LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH },
- { LANG_TROLL, 7341, SKILL_LANG_TROLL },
- { LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK },
- { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI },
- { LANG_ZOMBIE, 0, 0 },
- { LANG_GNOMISH_BINARY, 0, 0 },
- { LANG_GOBLIN_BINARY, 0, 0 }
-};
-
-LanguageDesc const* GetLanguageDescByID(uint32 lang)
-{
- for(int i = 0; i < LANGUAGES_COUNT; ++i)
- {
- if(uint32(lang_description[i].lang_id) == lang)
- return &lang_description[i];
- }
-
- return NULL;
-}
-
-ObjectMgr::ObjectMgr()
-{
- m_hiCharGuid = 1;
- m_hiCreatureGuid = 1;
- m_hiPetGuid = 1;
- m_hiItemGuid = 1;
- m_hiGoGuid = 1;
- m_hiDoGuid = 1;
- m_hiCorpseGuid = 1;
-
- m_hiPetNumber = 1;
-
- mGuildBankTabPrice.resize(GUILD_BANK_MAX_TABS);
- mGuildBankTabPrice[0] = 100;
- mGuildBankTabPrice[1] = 250;
- mGuildBankTabPrice[2] = 500;
- mGuildBankTabPrice[3] = 1000;
- mGuildBankTabPrice[4] = 2500;
- mGuildBankTabPrice[5] = 5000;
-
- // Only zero condition left, others will be added while loading DB tables
- mConditions.resize(1);
-}
-
-ObjectMgr::~ObjectMgr()
-{
- for( QuestMap::iterator i = mQuestTemplates.begin( ); i != mQuestTemplates.end( ); ++ i )
- {
- delete i->second;
- }
- mQuestTemplates.clear( );
-
- for( GossipTextMap::iterator i = mGossipText.begin( ); i != mGossipText.end( ); ++ i )
- {
- delete i->second;
- }
- mGossipText.clear( );
-
- mAreaTriggers.clear();
-
- for(PetLevelInfoMap::iterator i = petInfo.begin( ); i != petInfo.end( ); ++ i )
- {
- delete[] i->second;
- }
- petInfo.clear();
-
- // free only if loaded
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- delete[] playerClassInfo[class_].levelInfo;
-
- for (int race = 0; race < MAX_RACES; ++race)
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- delete[] playerInfo[race][class_].levelInfo;
-
- // free group and guild objects
- for (GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr)
- delete (*itr);
- for (GuildSet::iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
- delete (*itr);
-
- for (CachePlayerInfoMap::iterator itr = m_mPlayerInfoMap.begin(); itr != m_mPlayerInfoMap.end(); ++itr)
- delete itr->second;
-
- for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
- delete itr->second;
-
- for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
- itr->second.Clear();
-
- for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
- itr->second.Clear();
-}
-
-void ObjectMgr::LoadPlayerInfoInCache()
-{
- QueryResult *result = CharacterDatabase.PQuery("SELECT guid, name, data, class FROM characters");
- if(!result)
- {
- sLog.outError( "Loading Player Cache failed.");
- return;
- }
-
- PCachePlayerInfo pPPlayerInfo = NULL;
- Field *fields = NULL;
- Tokens tdata;
- barGoLink bar( result->GetRowCount() );
- do
- {
- bar.step();
- fields = result->Fetch();
- pPPlayerInfo = new CachePlayerInfo();
-
- pPPlayerInfo->sPlayerName = fields[1].GetString();
-
- tdata.clear();
- tdata = StrSplit(fields[2].GetCppString(), " ");
-
- pPPlayerInfo->unLevel = Player::GetUInt32ValueFromArray(tdata,UNIT_FIELD_LEVEL);
- pPPlayerInfo->unfield = Player::GetUInt32ValueFromArray(tdata,UNIT_FIELD_BYTES_0);
-
- pPPlayerInfo->unArenaInfoId0 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6);
- pPPlayerInfo->unArenaInfoId1 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6);
- pPPlayerInfo->unArenaInfoId2 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6);
-
- pPPlayerInfo->unArenaInfoSlot0 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5);
- pPPlayerInfo->unArenaInfoSlot1 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5);
- pPPlayerInfo->unArenaInfoSlot2 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5);
-
- pPPlayerInfo->unClass = (uint32)fields[3].GetUInt32();
- m_mPlayerInfoMap[fields[0].GetUInt32()] = pPPlayerInfo;
- }
- while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded info about %d players", m_mPlayerInfoMap.size());
-}
-
-PCachePlayerInfo ObjectMgr::GetPlayerInfoFromCache(uint32 unPlayerGuid) const
-{
- //Now m_mPlayerInfoMap is using only for search, but when dinamic inserting/removing
- //will be implemented we should lock it to prevent simultaneous access.
- //Inserting - when new created player is saving
- //Removing - when player has been deleted
- CachePlayerInfoMap::const_iterator ipos = m_mPlayerInfoMap.find(unPlayerGuid);
- return ipos == m_mPlayerInfoMap.end() ? NULL : ipos->second;
-}
-
-Group * ObjectMgr::GetGroupByLeader(const uint64 &guid) const
-{
- for(GroupSet::const_iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr)
- if ((*itr)->GetLeaderGUID() == guid)
- return *itr;
-
- return NULL;
-}
-
-Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const
-{
- for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++)
- if ((*itr)->GetId() == GuildId)
- return *itr;
-
- return NULL;
-}
-
-Guild * ObjectMgr::GetGuildByName(std::string guildname) const
-{
- for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++)
- if ((*itr)->GetName() == guildname)
- return *itr;
-
- return NULL;
-}
-
-std::string ObjectMgr::GetGuildNameById(const uint32 GuildId) const
-{
- for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++)
- if ((*itr)->GetId() == GuildId)
- return (*itr)->GetName();
-
- return "";
-}
-
-Guild* ObjectMgr::GetGuildByLeader(const uint64 &guid) const
-{
- for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
- if( (*itr)->GetLeader() == guid)
- return *itr;
-
- return NULL;
-}
-
-ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const
-{
- for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++)
- if ((*itr)->GetId() == ArenaTeamId)
- return *itr;
-
- return NULL;
-}
-
-ArenaTeam* ObjectMgr::GetArenaTeamByName(std::string arenateamname) const
-{
- for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++)
- if ((*itr)->GetName() == arenateamname)
- return *itr;
-
- return NULL;
-}
-
-ArenaTeam* ObjectMgr::GetArenaTeamByCapitan(uint64 const& guid) const
-{
- for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++)
- if ((*itr)->GetCaptain() == guid)
- return *itr;
-
- return NULL;
-}
-
-AuctionHouseObject * ObjectMgr::GetAuctionsMap( uint32 location )
-{
- switch ( location )
- {
- case 6: //horde
- return & mHordeAuctions;
- break;
- case 2: //alliance
- return & mAllianceAuctions;
- break;
- default: //neutral
- return & mNeutralAuctions;
- }
-}
-
-uint32 ObjectMgr::GetAuctionCut(uint32 location, uint32 highBid)
-{
- if (location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
- return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
- else
- return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
-}
-
-uint32 ObjectMgr::GetAuctionDeposit(uint32 location, uint32 time, Item *pItem)
-{
- float percentance; // in 0..1
- if ( location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
- percentance = 0.75f;
- else
- percentance = 0.15f;
-
- percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT);
-
- return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) );
-}
-
-/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
-uint32 ObjectMgr::GetAuctionOutBid(uint32 currentBid)
-{
- uint32 outbid = (currentBid / 100) * 5;
- if (!outbid)
- outbid = 1;
- return outbid;
-}
-
-//does not clear ram
-void ObjectMgr::SendAuctionWonMail( AuctionEntry *auction )
-{
- Item *pItem = GetAItem(auction->item_guidlow);
- if(!pItem)
- return;
-
- uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
- Player *bidder = GetPlayer(bidder_guid);
-
- uint32 bidder_accId = 0;
-
- // data for gm.log
- if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
- {
- uint32 bidder_security = 0;
- std::string bidder_name;
- if (bidder)
- {
- bidder_accId = bidder->GetSession()->GetAccountId();
- bidder_security = bidder->GetSession()->GetSecurity();
- bidder_name = bidder->GetName();
- }
- else
- {
- bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
- bidder_security = accmgr.GetSecurity(bidder_accId);
-
- if(bidder_security > SEC_PLAYER ) // not do redundant DB requests
- {
- if(!GetPlayerNameByGUID(bidder_guid,bidder_name))
- bidder_name = GetTrinityStringForDBCLocale(LANG_UNKNOWN);
- }
- }
-
- if( bidder_security > SEC_PLAYER )
- {
- std::string owner_name;
- if(!GetPlayerNameByGUID(auction->owner,owner_name))
- owner_name = GetTrinityStringForDBCLocale(LANG_UNKNOWN);
-
- uint32 owner_accid = GetPlayerAccountIdByGUID(auction->owner);
-
- sLog.outCommand("GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
- bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
- }
- }
- else if(!bidder)
- bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
-
- // receiver exist
- if(bidder || bidder_accId)
- {
- std::ostringstream msgAuctionWonSubject;
- msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
-
- std::ostringstream msgAuctionWonBody;
- msgAuctionWonBody.width(16);
- msgAuctionWonBody << std::right << std::hex << auction->owner;
- msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
- sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() );
-
- //prepare mail data... :
- uint32 itemTextId = this->CreateItemText( msgAuctionWonBody.str() );
-
- // set owner to bidder (to prevent delete item with sender char deleting)
- // owner in `data` will set at mail receive and item extracting
- CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
- CharacterDatabase.CommitTransaction();
-
- MailItemsInfo mi;
- mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
-
- if (bidder)
- bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template);
- else
- RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
-
- // will delete item or place to receiver mail list
- WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
- }
- // receiver not exist
- else
- {
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow());
- RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
- delete pItem;
- }
-}
-
-void ObjectMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
-{
- uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
- Player *owner = GetPlayer(owner_guid);
-
- // owner exist (online or offline)
- if(owner || GetPlayerAccountIdByGUID(owner_guid))
- {
- std::ostringstream msgAuctionSalePendingSubject;
- msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
-
- std::ostringstream msgAuctionSalePendingBody;
- uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
-
- time_t distrTime = time(NULL) + HOUR;
-
- msgAuctionSalePendingBody.width(16);
- msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
- msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
- msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
- msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
-
- sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
-
- uint32 itemTextId = this->CreateItemText( msgAuctionSalePendingBody.str() );
-
- WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
- }
-}
-
-//call this method to send mail to auction owner, when auction is successful, it does not clear ram
-void ObjectMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
-{
- uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
- Player *owner = GetPlayer(owner_guid);
-
- uint32 owner_accId = 0;
- if(!owner)
- owner_accId = GetPlayerAccountIdByGUID(owner_guid);
-
- // owner exist
- if(owner || owner_accId)
- {
- std::ostringstream msgAuctionSuccessfulSubject;
- msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
-
- std::ostringstream auctionSuccessfulBody;
- uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
-
- auctionSuccessfulBody.width(16);
- auctionSuccessfulBody << std::right << std::hex << auction->bidder;
- auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
- auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
-
- sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
-
- uint32 itemTextId = this->CreateItemText( auctionSuccessfulBody.str() );
-
- uint32 profit = auction->bid + auction->deposit - auctionCut;
-
- if (owner)
- {
- //send auction owner notification, bidder must be current!
- owner->GetSession()->SendAuctionOwnerNotification( auction );
- }
-
- WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR);
- }
-}
-
-//does not clear ram
-void ObjectMgr::SendAuctionExpiredMail( AuctionEntry * auction )
-{ //return an item in auction to its owner by mail
- Item *pItem = GetAItem(auction->item_guidlow);
- if(!pItem)
- {
- sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow);
- return;
- }
-
- uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
- Player *owner = GetPlayer(owner_guid);
-
- uint32 owner_accId = 0;
- if(!owner)
- owner_accId = GetPlayerAccountIdByGUID(owner_guid);
-
- // owner exist
- if(owner || owner_accId)
- {
- std::ostringstream subject;
- subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
-
- if ( owner )
- owner->GetSession()->SendAuctionOwnerNotification( auction );
- else
- RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
-
- MailItemsInfo mi;
- mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
-
- // will delete item or place to receiver mail list
- WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
-
- }
- // owner not found
- else
- {
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem->GetGUIDLow());
- RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
- delete pItem;
- }
-}
-
-CreatureInfo const* ObjectMgr::GetCreatureTemplate(uint32 id)
-{
- return sCreatureStorage.LookupEntry<CreatureInfo>(id);
-}
-
-void ObjectMgr::LoadCreatureLocales()
-{
- mCreatureLocaleMap.clear();
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,subname_loc1,name_loc2,subname_loc2,name_loc3,subname_loc3,name_loc4,subname_loc4,name_loc5,subname_loc5,name_loc6,subname_loc6,name_loc7,subname_loc7,name_loc8,subname_loc8 FROM locales_creature");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 creature locale strings. DB table `locales_creature` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- CreatureLocale& data = mCreatureLocaleMap[entry];
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[1+2*(i-1)].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Name.size() <= idx)
- data.Name.resize(idx+1);
-
- data.Name[idx] = str;
- }
- }
- str = fields[1+2*(i-1)+1].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.SubName.size() <= idx)
- data.SubName.resize(idx+1);
-
- data.SubName[idx] = str;
- }
- }
- }
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() );
-}
-
-void ObjectMgr::LoadNpcOptionLocales()
-{
- mNpcOptionLocaleMap.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,"
- "option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2,"
- "option_text_loc3,box_text_loc3,option_text_loc4,box_text_loc4,"
- "option_text_loc5,box_text_loc5,option_text_loc6,box_text_loc6,"
- "option_text_loc7,box_text_loc7,option_text_loc8,box_text_loc8 "
- "FROM locales_npc_option");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- NpcOptionLocale& data = mNpcOptionLocaleMap[entry];
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[1+2*(i-1)].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.OptionText.size() <= idx)
- data.OptionText.resize(idx+1);
-
- data.OptionText[idx] = str;
- }
- }
- str = fields[1+2*(i-1)+1].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.BoxText.size() <= idx)
- data.BoxText.resize(idx+1);
-
- data.BoxText[idx] = str;
- }
- }
- }
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u npc_option locale strings", mNpcOptionLocaleMap.size() );
-}
-
-void ObjectMgr::LoadCreatureTemplates()
-{
- sCreatureStorage.Load();
-
- sLog.outString( ">> Loaded %u creature definitions", sCreatureStorage.RecordCount );
- sLog.outString();
-
- std::set<uint32> heroicEntries; // already loaded heroic value in creatures
- std::set<uint32> hasHeroicEntries; // already loaded creatures with heroic entry values
-
- // check data correctness
- for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i)
- {
- CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i);
- if(!cInfo)
- continue;
-
- if(cInfo->HeroicEntry)
- {
- CreatureInfo const* heroicInfo = GetCreatureTemplate(cInfo->HeroicEntry);
- if(!heroicInfo)
- {
- sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u not exist.",cInfo->HeroicEntry,cInfo->HeroicEntry);
- continue;
- }
-
- if(heroicEntries.find(i)!=heroicEntries.end())
- {
- sLog.outErrorDb("Creature (Entry: %u) listed as heroic but have value in `heroic_entry`.",i);
- continue;
- }
-
- if(heroicEntries.find(cInfo->HeroicEntry)!=heroicEntries.end())
- {
- sLog.outErrorDb("Creature (Entry: %u) already listed as heroic for another entry.",cInfo->HeroicEntry);
- continue;
- }
-
- if(hasHeroicEntries.find(cInfo->HeroicEntry)!=hasHeroicEntries.end())
- {
- sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u have heroic entry also.",i,cInfo->HeroicEntry,cInfo->HeroicEntry);
- continue;
- }
-
- if(cInfo->npcflag != heroicInfo->npcflag)
- {
- sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `npcflag` in heroic mode.",i);
- continue;
- }
-
- if(cInfo->classNum != heroicInfo->classNum)
- {
- sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `classNum` in heroic mode.",i);
- continue;
- }
-
- if(cInfo->race != heroicInfo->race)
- {
- sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `race` in heroic mode.",i);
- continue;
- }
-
- if(cInfo->trainer_type != heroicInfo->trainer_type)
- {
- sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `trainer_type` in heroic mode.",i);
- continue;
- }
-
- if(cInfo->trainer_spell != heroicInfo->trainer_spell)
- {
- sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `trainer_spell` in heroic mode.",i);
- continue;
- }
-
- hasHeroicEntries.insert(i);
- heroicEntries.insert(cInfo->HeroicEntry);
- }
-
- FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_A);
- if(!factionTemplate)
- sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_A template (%u)", cInfo->Entry, cInfo->faction_A);
-
- factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_H);
- if(!factionTemplate)
- sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
-
- // check model ids, supplying and sending non-existent ids to the client might crash them
- if(cInfo->Modelid1 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid1))
- {
- sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u), setting it to 0", cInfo->Entry, cInfo->Modelid1);
- const_cast<CreatureInfo*>(cInfo)->Modelid1 = 0;
- }
- if(cInfo->Modelid2 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid2))
- {
- sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid2);
- const_cast<CreatureInfo*>(cInfo)->Modelid2 = 0;
- }
- if(cInfo->Modelid3 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid3))
- {
- sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u), setting it to 0", cInfo->Entry, cInfo->Modelid3);
- const_cast<CreatureInfo*>(cInfo)->Modelid3 = 0;
- }
- if(cInfo->Modelid4 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid4))
- {
- sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid4);
- const_cast<CreatureInfo*>(cInfo)->Modelid4 = 0;
- }
-
- if(cInfo->dmgschool >= MAX_SPELL_SCHOOL)
- {
- sLog.outErrorDb("Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`",cInfo->Entry,cInfo->dmgschool);
- const_cast<CreatureInfo*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL;
- }
-
- if(cInfo->baseattacktime == 0)
- const_cast<CreatureInfo*>(cInfo)->baseattacktime = BASE_ATTACK_TIME;
-
- if(cInfo->rangeattacktime == 0)
- const_cast<CreatureInfo*>(cInfo)->rangeattacktime = BASE_ATTACK_TIME;
-
- if((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE)
- sLog.outErrorDb("Creature (Entry: %u) has wrong trainer type %u",cInfo->Entry,cInfo->trainer_type);
-
- if(cInfo->InhabitType <= 0 || cInfo->InhabitType > INHABIT_ANYWHERE)
- {
- sLog.outErrorDb("Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly",cInfo->Entry,cInfo->InhabitType);
- const_cast<CreatureInfo*>(cInfo)->InhabitType = INHABIT_ANYWHERE;
- }
-
- if(cInfo->PetSpellDataId)
- {
- CreatureSpellDataEntry const* spellDataId = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId);
- if(!spellDataId)
- sLog.outErrorDb("Creature (Entry: %u) has non-existing PetSpellDataId (%u)", cInfo->Entry, cInfo->PetSpellDataId);
- }
-
- if(cInfo->MovementType >= MAX_DB_MOTION_TYPE)
- {
- sLog.outErrorDb("Creature (Entry: %u) has wrong movement generator type (%u), ignore and set to IDLE.",cInfo->Entry,cInfo->MovementType);
- const_cast<CreatureInfo*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
- }
-
- if(cInfo->equipmentId > 0) // 0 no equipment
- {
- if(!GetEquipmentInfo(cInfo->equipmentId))
- {
- sLog.outErrorDb("Table `creature_template` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", cInfo->Entry, cInfo->equipmentId);
- const_cast<CreatureInfo*>(cInfo)->equipmentId = 0;
- }
- }
-
- /// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
- if(cInfo->scale <= 0.0f)
- {
- uint32 modelid = cInfo->GetFirstValidModelId();
- CreatureDisplayInfoEntry const* ScaleEntry = sCreatureDisplayInfoStore.LookupEntry(modelid);
- const_cast<CreatureInfo*>(cInfo)->scale = ScaleEntry ? ScaleEntry->scale : 1.0f;
- }
- }
-}
-
-void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr)
-{
- // Now add the auras, format "spellid effectindex spellid effectindex..."
- char *p,*s;
- std::vector<int> val;
- s=p=(char*)reinterpret_cast<char const*>(addon->auras);
- if(p)
- {
- while (p[0]!=0)
- {
- ++p;
- if (p[0]==' ')
- {
- val.push_back(atoi(s));
- s=++p;
- }
- }
- if (p!=s)
- val.push_back(atoi(s));
-
- // free char* loaded memory
- delete[] (char*)reinterpret_cast<char const*>(addon->auras);
-
- // wrong list
- if (val.size()%2)
- {
- addon->auras = NULL;
- sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`.",guidEntryStr,addon->guidOrEntry,table);
- return;
- }
- }
-
- // empty list
- if(val.empty())
- {
- addon->auras = NULL;
- return;
- }
-
- // replace by new structures array
- const_cast<CreatureDataAddonAura*&>(addon->auras) = new CreatureDataAddonAura[val.size()/2+1];
-
- int i=0;
- for(int j=0;j<val.size()/2;++j)
- {
- CreatureDataAddonAura& cAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]);
- cAura.spell_id = (uint32)val[2*j+0];
- cAura.effect_idx = (uint32)val[2*j+1];
- if ( cAura.effect_idx > 2 )
- {
- sLog.outErrorDb("Creature (%s: %u) has wrong effect %u for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table);
- continue;
- }
- SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura.spell_id);
- if (!AdditionalSpellInfo)
- {
- sLog.outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table);
- continue;
- }
-
- if (!AdditionalSpellInfo->Effect[cAura.effect_idx] || !AdditionalSpellInfo->EffectApplyAuraName[cAura.effect_idx])
- {
- sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table);
- continue;
- }
-
- ++i;
- }
-
- // fill terminator element (after last added)
- CreatureDataAddonAura& endAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]);
- endAura.spell_id = 0;
- endAura.effect_idx = 0;
-}
-
-void ObjectMgr::LoadCreatureAddons()
-{
- sCreatureInfoAddonStorage.Load();
-
- sLog.outString( ">> Loaded %u creature template addons", sCreatureInfoAddonStorage.RecordCount );
- sLog.outString();
-
- // check data correctness and convert 'auras'
- for(uint32 i = 1; i < sCreatureInfoAddonStorage.MaxEntry; ++i)
- {
- CreatureDataAddon const* addon = sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(i);
- if(!addon)
- continue;
-
- ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), "creature_template_addon", "Entry");
-
- if(!sCreatureStorage.LookupEntry<CreatureInfo>(addon->guidOrEntry))
- sLog.outErrorDb("Creature (Entry: %u) does not exist but has a record in `creature_template_addon`",addon->guidOrEntry);
- }
-
- sCreatureDataAddonStorage.Load();
-
- sLog.outString( ">> Loaded %u creature addons", sCreatureDataAddonStorage.RecordCount );
- sLog.outString();
-
- // check data correctness and convert 'auras'
- for(uint32 i = 1; i < sCreatureDataAddonStorage.MaxEntry; ++i)
- {
- CreatureDataAddon const* addon = sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(i);
- if(!addon)
- continue;
-
- ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), "creature_addon", "GUIDLow");
-
- if(mCreatureDataMap.find(addon->guidOrEntry)==mCreatureDataMap.end())
- sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`",addon->guidOrEntry);
- }
-}
-
-EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry)
-{
- return sEquipmentStorage.LookupEntry<EquipmentInfo>(entry);
-}
-
-void ObjectMgr::LoadEquipmentTemplates()
-{
- sEquipmentStorage.Load();
-
- sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );
- sLog.outString();
-}
-
-CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
-{
- return sCreatureModelStorage.LookupEntry<CreatureModelInfo>(modelid);
-}
-
-uint32 ObjectMgr::ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data)
-{
- // Load creature model (display id)
- uint32 display_id = 0;
-
- if (!data || data->displayid == 0) // use defaults from the template
- {
- display_id = cinfo->GetRandomValidModelId();
- } else display_id = data->displayid; // overwritten from creature data
-
- return display_id;
-}
-
-CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(uint32 display_id)
-{
- CreatureModelInfo const *minfo = GetCreatureModelInfo(display_id);
- if(!minfo)
- return NULL;
-
- // If a model for another gender exists, 50% chance to use it
- if(minfo->modelid_other_gender != 0 && urand(0,1) == 0)
- {
- CreatureModelInfo const *minfo_tmp = GetCreatureModelInfo(minfo->modelid_other_gender);
- if(!minfo_tmp)
- {
- sLog.outErrorDb("Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", minfo->modelid, minfo->modelid_other_gender);
- return minfo; // not fatal, just use the previous one
- }
- else
- return minfo_tmp;
- }
- else
- return minfo;
-}
-
-void ObjectMgr::LoadCreatureModelInfo()
-{
- sCreatureModelStorage.Load();
-
- sLog.outString( ">> Loaded %u creature model based info", sCreatureModelStorage.RecordCount );
- sLog.outString();
-
- // check if combat_reach is valid
- for(uint32 i = 1; i < sCreatureModelStorage.MaxEntry; ++i)
- {
- CreatureModelInfo const* mInfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(i);
- if(!mInfo)
- continue;
-
- if(mInfo->combat_reach < 0.5f)
- {
- //sLog.outErrorDb("Creature model (Entry: %u) has invalid combat reach (%f), setting it to 0.5", mInfo->modelid, mInfo->combat_reach);
- const_cast<CreatureModelInfo*>(mInfo)->combat_reach = 0.5f;
- }
- }
-}
-
-void ObjectMgr::LoadCreatures()
-{
- uint32 count = 0;
- // 0 1 2 3
- QueryResult *result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid,"
- // 4 5 6 7 8 9 10 11
- "equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint,"
- // 12 13 14 15 16 17
- "curhealth, curmana, DeathState, MovementType, spawnMask, event "
- "FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outErrorDb(">> Loaded 0 creature. DB table `creature` is empty.");
- return;
- }
-
- // build single time for check creature data
- std::set<uint32> heroicCreatures;
- for(uint32 i = 0; i < sCreatureStorage.MaxEntry; ++i)
- if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
- if(cInfo->HeroicEntry)
- heroicCreatures.insert(cInfo->HeroicEntry);
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 guid = fields[0].GetUInt32();
-
- CreatureData& data = mCreatureDataMap[guid];
-
- data.id = fields[ 1].GetUInt32();
- data.mapid = fields[ 2].GetUInt32();
- data.displayid = fields[ 3].GetUInt32();
- data.equipmentId = fields[ 4].GetUInt32();
- data.posX = fields[ 5].GetFloat();
- data.posY = fields[ 6].GetFloat();
- data.posZ = fields[ 7].GetFloat();
- data.orientation = fields[ 8].GetFloat();
- data.spawntimesecs = fields[ 9].GetUInt32();
- data.spawndist = fields[10].GetFloat();
- data.currentwaypoint= fields[11].GetUInt32();
- data.curhealth = fields[12].GetUInt32();
- data.curmana = fields[13].GetUInt32();
- data.is_dead = fields[14].GetBool();
- data.movementType = fields[15].GetUInt8();
- data.spawnMask = fields[16].GetUInt8();
- int16 gameEvent = fields[17].GetInt16();
-
- CreatureInfo const* cInfo = GetCreatureTemplate(data.id);
- if(!cInfo)
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u) with not existed creature entry %u, skipped.",guid,data.id );
- continue;
- }
-
- if(heroicCreatures.find(data.id)!=heroicCreatures.end())
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u) that listed as heroic template in `creature_template_substitution`, skipped.",guid,data.id );
- continue;
- }
-
- if(data.equipmentId > 0) // -1 no equipment, 0 use default
- {
- if(!GetEquipmentInfo(data.equipmentId))
- {
- sLog.outErrorDb("Table `creature` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", data.id, data.equipmentId);
- data.equipmentId = -1;
- }
- }
-
- if(cInfo->RegenHealth && data.curhealth < cInfo->minhealth)
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`RegenHealth`=1 and low current health (%u), `creature_template`.`minhealth`=%u.",guid,data.id,data.curhealth, cInfo->minhealth );
- data.curhealth = cInfo->minhealth;
- }
-
- if(data.curmana < cInfo->minmana)
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with low current mana (%u), `creature_template`.`minmana`=%u.",guid,data.id,data.curmana, cInfo->minmana );
- data.curmana = cInfo->minmana;
- }
-
- if(data.spawndist < 0.0f)
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `spawndist`< 0, set to 0.",guid,data.id );
- data.spawndist = 0.0f;
- }
- else if(data.movementType == RANDOM_MOTION_TYPE)
- {
- if(data.spawndist == 0.0f)
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=1 (random movement) but with `spawndist`=0, replace by idle movement type (0).",guid,data.id );
- data.movementType = IDLE_MOTION_TYPE;
- }
- }
- else if(data.movementType == IDLE_MOTION_TYPE)
- {
- if(data.spawndist != 0.0f)
- {
- sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=0 (idle) have `spawndist`<>0, set to 0.",guid,data.id );
- data.spawndist = 0.0f;
- }
- }
-
- if (gameEvent==0) // if not this is to be managed by GameEvent System
- AddCreatureToGrid(guid, &data);
- ++count;
-
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u creatures", mCreatureDataMap.size() );
-}
-
-void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
-{
- uint8 mask = data->spawnMask;
- for(uint8 i = 0; mask != 0; i++, mask >>= 1)
- {
- if(mask & 1)
- {
- CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
- uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
- cell_guids.creatures.insert(guid);
- }
- }
-}
-
-void ObjectMgr::RemoveCreatureFromGrid(uint32 guid, CreatureData const* data)
-{
- uint8 mask = data->spawnMask;
- for(uint8 i = 0; mask != 0; i++, mask >>= 1)
- {
- if(mask & 1)
- {
- CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
- uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
- cell_guids.creatures.erase(guid);
- }
- }
-}
-
-void ObjectMgr::LoadGameobjects()
-{
- uint32 count = 0;
-
- // 0 1 2 3 4 5 6
- QueryResult *result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation,"
- // 7 8 9 10 11 12 13 14 15
- "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, event "
- "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 guid = fields[0].GetUInt32();
-
- GameObjectData& data = mGameObjectDataMap[guid];
-
- data.id = fields[ 1].GetUInt32();
- data.mapid = fields[ 2].GetUInt32();
- data.posX = fields[ 3].GetFloat();
- data.posY = fields[ 4].GetFloat();
- data.posZ = fields[ 5].GetFloat();
- data.orientation = fields[ 6].GetFloat();
- data.rotation0 = fields[ 7].GetFloat();
- data.rotation1 = fields[ 8].GetFloat();
- data.rotation2 = fields[ 9].GetFloat();
- data.rotation3 = fields[10].GetFloat();
- data.spawntimesecs = fields[11].GetInt32();
- data.animprogress = fields[12].GetUInt32();
- data.go_state = fields[13].GetUInt32();
- data.ArtKit = 0;
- data.spawnMask = fields[14].GetUInt8();
- int16 gameEvent = fields[15].GetInt16();
-
- GameObjectInfo const* gInfo = GetGameObjectInfo(data.id);
- if(!gInfo)
- {
- sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u) with not existed gameobject entry %u, skipped.",guid,data.id );
- continue;
- }
-
- if (gameEvent==0) // if not this is to be managed by GameEvent System
- AddGameobjectToGrid(guid, &data);
- ++count;
-
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u gameobjects", mGameObjectDataMap.size());
-}
-
-void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
-{
- uint8 mask = data->spawnMask;
- for(uint8 i = 0; mask != 0; i++, mask >>= 1)
- {
- if(mask & 1)
- {
- CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
- uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
- cell_guids.gameobjects.insert(guid);
- }
- }
-}
-
-void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data)
-{
- uint8 mask = data->spawnMask;
- for(uint8 i = 0; mask != 0; i++, mask >>= 1)
- {
- if(mask & 1)
- {
- CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
- uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
- cell_guids.gameobjects.erase(guid);
- }
- }
-}
-
-void ObjectMgr::LoadCreatureRespawnTimes()
-{
- // remove outdated data
- WorldDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
-
- uint32 count = 0;
-
- QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM creature_respawn");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString();
- sLog.outString(">> Loaded 0 creature respawn time.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 loguid = fields[0].GetUInt32();
- uint64 respawn_time = fields[1].GetUInt64();
- uint32 instance = fields[2].GetUInt32();
-
- mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time);
-
- ++count;
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString( ">> Loaded %u creature respawn times", mCreatureRespawnTimes.size() );
- sLog.outString();
-}
-
-void ObjectMgr::LoadGameobjectRespawnTimes()
-{
- // remove outdated data
- WorldDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
-
- uint32 count = 0;
-
- QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM gameobject_respawn");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString();
- sLog.outString(">> Loaded 0 gameobject respawn time.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 loguid = fields[0].GetUInt32();
- uint64 respawn_time = fields[1].GetUInt64();
- uint32 instance = fields[2].GetUInt32();
-
- mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time);
-
- ++count;
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString( ">> Loaded %u gameobject respawn times", mGORespawnTimes.size() );
- sLog.outString();
-}
-
-// name must be checked to correctness (if received) before call this function
-uint64 ObjectMgr::GetPlayerGUIDByName(std::string name) const
-{
- uint64 guid = 0;
-
- CharacterDatabase.escape_string(name);
-
- // Player name safe to sending to DB (checked at login) and this function using
- QueryResult *result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE name = '%s'", name.c_str());
- if(result)
- {
- guid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
-
- delete result;
- }
-
- return guid;
-}
-
-bool ObjectMgr::GetPlayerNameByGUID(const uint64 &guid, std::string &name) const
-{
- // prevent DB access for online player
- if(Player* player = GetPlayer(guid))
- {
- name = player->GetName();
- return true;
- }
-
- PCachePlayerInfo pInfo = GetPlayerInfoFromCache(GUID_LOPART(guid));
- if(pInfo)
- {
- name = pInfo->sPlayerName.c_str();
- return true;
- }
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
-
- if(result)
- {
- name = (*result)[0].GetCppString();
- delete result;
- return true;
- }
-
- return false;
-}
-
-uint32 ObjectMgr::GetPlayerTeamByGUID(const uint64 &guid) const
-{
- QueryResult *result = CharacterDatabase.PQuery("SELECT race FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
-
- if(result)
- {
- uint8 race = (*result)[0].GetUInt8();
- delete result;
- return Player::TeamForRace(race);
- }
-
- return 0;
-}
-
-uint32 ObjectMgr::GetPlayerAccountIdByGUID(const uint64 &guid) const
-{
- QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
- if(result)
- {
- uint32 acc = (*result)[0].GetUInt32();
- delete result;
- return acc;
- }
-
- return 0;
-}
-
-uint32 ObjectMgr::GetPlayerAccountIdByPlayerName(std::string name) const
-{
- QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", name.c_str());
- if(result)
- {
- uint32 acc = (*result)[0].GetUInt32();
- delete result;
- return acc;
- }
-
- return 0;
-}
-
-void ObjectMgr::LoadAuctions()
-{
- QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
- if( !result )
- return;
-
- Field *fields = result->Fetch();
- uint32 AuctionCount=fields[0].GetUInt32();
- delete result;
-
- if(!AuctionCount)
- return;
-
- result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" );
- if( !result )
- return;
-
- barGoLink bar( AuctionCount );
-
- AuctionEntry *aItem;
-
- do
- {
- fields = result->Fetch();
-
- bar.step();
-
- aItem = new AuctionEntry;
- aItem->Id = fields[0].GetUInt32();
- aItem->auctioneer = fields[1].GetUInt32();
- aItem->item_guidlow = fields[2].GetUInt32();
- aItem->item_template = fields[3].GetUInt32();
- aItem->owner = fields[4].GetUInt32();
- aItem->buyout = fields[5].GetUInt32();
- aItem->time = fields[6].GetUInt32();
- aItem->bidder = fields[7].GetUInt32();
- aItem->bid = fields[8].GetUInt32();
- aItem->startbid = fields[9].GetUInt32();
- aItem->deposit = fields[10].GetUInt32();
- aItem->location = fields[11].GetUInt8();
- //check if sold item exists
- if ( this->GetAItem( aItem->item_guidlow ) )
- {
- GetAuctionsMap( aItem->location )->AddAuction(aItem);
- }
- else
- {
- CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
- sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
- delete aItem;
- }
- } while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u auctions", AuctionCount );
- sLog.outString();
-}
-
-void ObjectMgr::LoadItemLocales()
-{
- mItemLocaleMap.clear();
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,description_loc1,name_loc2,description_loc2,name_loc3,description_loc3,name_loc4,description_loc4,name_loc5,description_loc5,name_loc6,description_loc6,name_loc7,description_loc7,name_loc8,description_loc8 FROM locales_item");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 Item locale strings. DB table `locales_item` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- ItemLocale& data = mItemLocaleMap[entry];
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[1+2*(i-1)].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Name.size() <= idx)
- data.Name.resize(idx+1);
-
- data.Name[idx] = str;
- }
- }
-
- str = fields[1+2*(i-1)+1].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Description.size() <= idx)
- data.Description.resize(idx+1);
-
- data.Description[idx] = str;
- }
- }
- }
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u Item locale strings", mItemLocaleMap.size() );
-}
-
-void ObjectMgr::LoadItemPrototypes()
-{
- sItemStorage.Load ();
- sLog.outString( ">> Loaded %u item prototypes", sItemStorage.RecordCount );
- sLog.outString();
-
- // check data correctness
- for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i)
- {
- ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype >(i);
- ItemEntry const *dbcitem = sItemStore.LookupEntry(i);
- if(!proto)
- {
- /* to many errors, and possible not all items really used in game
- if (dbcitem)
- sLog.outErrorDb("Item (Entry: %u) doesn't exists in DB, but must exist.",i);
- */
- continue;
- }
-
- if(dbcitem)
- {
- if(proto->InventoryType != dbcitem->InventoryType)
- {
- sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).",i,proto->InventoryType,dbcitem->InventoryType);
- // It safe let use InventoryType from DB
- }
-
- if(proto->DisplayInfoID != dbcitem->DisplayId)
- {
- sLog.outErrorDb("Item (Entry: %u) not correct %u display id, must be %u (using it).",i,proto->DisplayInfoID,dbcitem->DisplayId);
- const_cast<ItemPrototype*>(proto)->DisplayInfoID = dbcitem->DisplayId;
- }
- if(proto->Sheath != dbcitem->Sheath)
- {
- sLog.outErrorDb("Item (Entry: %u) not correct %u sheath, must be %u (using it).",i,proto->Sheath,dbcitem->Sheath);
- const_cast<ItemPrototype*>(proto)->Sheath = dbcitem->Sheath;
- }
- }
- else
- {
- sLog.outErrorDb("Item (Entry: %u) not correct (not listed in list of existed items).",i);
- }
-
- if(proto->Class >= MAX_ITEM_CLASS)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class);
- const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_JUNK;
- }
-
- if(proto->SubClass >= MaxItemSubclassValues[proto->Class])
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong Subclass value (%u) for class %u",i,proto->SubClass,proto->Class);
- const_cast<ItemPrototype*>(proto)->SubClass = 0;// exist for all item classes
- }
-
- if(proto->Quality >= MAX_ITEM_QUALITY)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong Quality value (%u)",i,proto->Quality);
- const_cast<ItemPrototype*>(proto)->Quality = ITEM_QUALITY_NORMAL;
- }
-
- if(proto->BuyCount <= 0)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong BuyCount value (%u), set to default(1).",i,proto->BuyCount);
- const_cast<ItemPrototype*>(proto)->BuyCount = 1;
- }
-
- if(proto->InventoryType >= MAX_INVTYPE)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong InventoryType value (%u)",i,proto->InventoryType);
- const_cast<ItemPrototype*>(proto)->InventoryType = INVTYPE_NON_EQUIP;
- }
-
- if(proto->RequiredSkill >= MAX_SKILL_TYPE)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong RequiredSkill value (%u)",i,proto->RequiredSkill);
- const_cast<ItemPrototype*>(proto)->RequiredSkill = 0;
- }
-
- if(!(proto->AllowableClass & CLASSMASK_ALL_PLAYABLE))
- {
- sLog.outErrorDb("Item (Entry: %u) not have in `AllowableClass` any playable classes (%u) and can't be equipped.",i,proto->AllowableClass);
- }
-
- if(!(proto->AllowableRace & RACEMASK_ALL_PLAYABLE))
- {
- sLog.outErrorDb("Item (Entry: %u) not have in `AllowableRace` any playable races (%u) and can't be equipped.",i,proto->AllowableRace);
- }
-
- if(proto->RequiredSpell && !sSpellStore.LookupEntry(proto->RequiredSpell))
- {
- sLog.outErrorDb("Item (Entry: %u) have wrong (non-existed) spell in RequiredSpell (%u)",i,proto->RequiredSpell);
- const_cast<ItemPrototype*>(proto)->RequiredSpell = 0;
- }
-
- if(proto->RequiredReputationRank >= MAX_REPUTATION_RANK)
- sLog.outErrorDb("Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used.",i,proto->RequiredReputationRank);
-
- if(proto->RequiredReputationFaction)
- {
- if(!sFactionStore.LookupEntry(proto->RequiredReputationFaction))
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)",i,proto->RequiredReputationFaction);
- const_cast<ItemPrototype*>(proto)->RequiredReputationFaction = 0;
- }
-
- if(proto->RequiredReputationRank == MIN_REPUTATION_RANK)
- sLog.outErrorDb("Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.",i);
- }
- else if(proto->RequiredReputationRank > MIN_REPUTATION_RANK)
- sLog.outErrorDb("Item (Entry: %u) has RequiredReputationFaction ==0 but RequiredReputationRank > 0, rank setting is useless.",i);
-
- if(proto->Stackable==0)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%u), replace by default 1.",i,proto->Stackable);
- const_cast<ItemPrototype*>(proto)->Stackable = 1;
- }
- else if(proto->Stackable > 255)
- {
- sLog.outErrorDb("Item (Entry: %u) has too large value in stackable (%u), replace by hardcoded upper limit (255).",i,proto->Stackable);
- const_cast<ItemPrototype*>(proto)->Stackable = 255;
- }
-
- for (int j = 0; j < 10; j++)
- {
- // for ItemStatValue != 0
- if(proto->ItemStat[j].ItemStatValue && proto->ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong stat_type%d (%u)",i,j+1,proto->ItemStat[j].ItemStatType);
- const_cast<ItemPrototype*>(proto)->ItemStat[j].ItemStatType = 0;
- }
- }
-
- for (int j = 0; j < 5; j++)
- {
- if(proto->Damage[j].DamageType >= MAX_SPELL_SCHOOL)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong dmg_type%d (%u)",i,j+1,proto->Damage[j].DamageType);
- const_cast<ItemPrototype*>(proto)->Damage[j].DamageType = 0;
- }
- }
-
- // special format
- if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN)
- {
- // spell_1
- if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format",i,0+1,proto->Spells[0].SpellTrigger);
- const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
-
- // spell_2 have learning spell
- if(proto->Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.",i,1+1,proto->Spells[1].SpellTrigger);
- const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- else if(!proto->Spells[1].SpellId)
- {
- sLog.outErrorDb("Item (Entry: %u) not has expected spell in spellid_%d in special learning format.",i,1+1);
- const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- else
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[1].SpellId);
- if(!spellInfo)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);
- const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- // allowed only in special format
- else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN)
- {
- sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);
- const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- }
-
- // spell_3*,spell_4*,spell_5* is empty
- for (int j = 2; j < 5; j++)
- {
- if(proto->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger);
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- else if(proto->Spells[j].SpellId != 0)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong spell in spellid_%d (%u) for learning special format",i,j+1,proto->Spells[j].SpellId);
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
- }
- }
- }
- // normal spell list
- else
- {
- for (int j = 0; j < 5; j++)
- {
- if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger);
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
-
- if(proto->Spells[j].SpellId)
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[j].SpellId);
- if(!spellInfo)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
- }
- // allowed only in special format
- else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN)
- {
- sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);
- const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
- }
- }
- }
- }
-
- if(proto->Bonding >= MAX_BIND_TYPE)
- sLog.outErrorDb("Item (Entry: %u) has wrong Bonding value (%u)",i,proto->Bonding);
-
- if(proto->PageText && !sPageTextStore.LookupEntry<PageText>(proto->PageText))
- sLog.outErrorDb("Item (Entry: %u) has non existing first page (Id:%u)", i,proto->PageText);
-
- if(proto->LockID && !sLockStore.LookupEntry(proto->LockID))
- sLog.outErrorDb("Item (Entry: %u) has wrong LockID (%u)",i,proto->LockID);
-
- if(proto->Sheath >= MAX_SHEATHETYPE)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong Sheath (%u)",i,proto->Sheath);
- const_cast<ItemPrototype*>(proto)->Sheath = SHEATHETYPE_NONE;
- }
-
- if(proto->RandomProperty && !sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(proto->RandomProperty)))
- {
- sLog.outErrorDb("Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)",i,proto->RandomProperty);
- const_cast<ItemPrototype*>(proto)->RandomProperty = 0;
- }
-
- if(proto->RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(proto->RandomSuffix)))
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong RandomSuffix (%u)",i,proto->RandomSuffix);
- const_cast<ItemPrototype*>(proto)->RandomSuffix = 0;
- }
-
- if(proto->ItemSet && !sItemSetStore.LookupEntry(proto->ItemSet))
- {
- sLog.outErrorDb("Item (Entry: %u) have wrong ItemSet (%u)",i,proto->ItemSet);
- const_cast<ItemPrototype*>(proto)->ItemSet = 0;
- }
-
- if(proto->Area && !GetAreaEntryByAreaID(proto->Area))
- sLog.outErrorDb("Item (Entry: %u) has wrong Area (%u)",i,proto->Area);
-
- if(proto->Map && !sMapStore.LookupEntry(proto->Map))
- sLog.outErrorDb("Item (Entry: %u) has wrong Map (%u)",i,proto->Map);
-
- if(proto->TotemCategory && !sTotemCategoryStore.LookupEntry(proto->TotemCategory))
- sLog.outErrorDb("Item (Entry: %u) has wrong TotemCategory (%u)",i,proto->TotemCategory);
-
- for (int j = 0; j < 3; j++)
- {
- if(proto->Socket[j].Color && (proto->Socket[j].Color & SOCKET_COLOR_ALL) != proto->Socket[j].Color)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong socketColor_%d (%u)",i,j+1,proto->Socket[j].Color);
- const_cast<ItemPrototype*>(proto)->Socket[j].Color = 0;
- }
- }
-
- if(proto->GemProperties && !sGemPropertiesStore.LookupEntry(proto->GemProperties))
- sLog.outErrorDb("Item (Entry: %u) has wrong GemProperties (%u)",i,proto->GemProperties);
-
- if(proto->FoodType >= MAX_PET_DIET)
- {
- sLog.outErrorDb("Item (Entry: %u) has wrong FoodType value (%u)",i,proto->FoodType);
- const_cast<ItemPrototype*>(proto)->FoodType = 0;
- }
- }
-
- // this DBC used currently only for check item templates in DB.
- sItemStore.Clear();
-}
-
-void ObjectMgr::LoadAuctionItems()
-{
- QueryResult *result = CharacterDatabase.Query( "SELECT itemguid,item_template FROM auctionhouse" );
-
- if( !result )
- return;
-
- barGoLink bar( result->GetRowCount() );
-
- uint32 count = 0;
-
- Field *fields;
- do
- {
- bar.step();
-
- fields = result->Fetch();
- uint32 item_guid = fields[0].GetUInt32();
- uint32 item_template = fields[1].GetUInt32();
-
- ItemPrototype const *proto = GetItemPrototype(item_template);
-
- if(!proto)
- {
- sLog.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template);
- continue;
- }
-
- Item *item = NewItemOrBag(proto);
-
- if(!item->LoadFromDB(item_guid,0))
- {
- delete item;
- continue;
- }
- AddAItem(item);
-
- ++count;
- }
- while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u auction items", count );
-}
-
-void ObjectMgr::LoadPetLevelInfo()
-{
- // Loading levels data
- {
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult *result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u level pet stats definitions", count );
- sLog.outErrorDb( "Error loading `pet_levelstats` table or empty table.");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 creature_id = fields[0].GetUInt32();
- if(!sCreatureStorage.LookupEntry<CreatureInfo>(creature_id))
- {
- sLog.outErrorDb("Wrong creature id %u in `pet_levelstats` table, ignoring.",creature_id);
- continue;
- }
-
- uint32 current_level = fields[1].GetUInt32();
- if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- if(current_level > 255) // hardcoded level maximum
- sLog.outErrorDb("Wrong (> 255) level %u in `pet_levelstats` table, ignoring.",current_level);
- else
- sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `pet_levelstats` table, ignoring.",current_level);
- continue;
- }
- else if(current_level < 1)
- {
- sLog.outErrorDb("Wrong (<1) level %u in `pet_levelstats` table, ignoring.",current_level);
- continue;
- }
-
- PetLevelInfo*& pInfoMapEntry = petInfo[creature_id];
-
- if(pInfoMapEntry==NULL)
- pInfoMapEntry = new PetLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)];
-
- // data for level 1 stored in [0] array element, ...
- PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level-1];
-
- pLevelInfo->health = fields[2].GetUInt16();
- pLevelInfo->mana = fields[3].GetUInt16();
- pLevelInfo->armor = fields[9].GetUInt16();
-
- for (int i = 0; i < MAX_STATS; i++)
- {
- pLevelInfo->stats[i] = fields[i+4].GetUInt16();
- }
-
- bar.step();
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u level pet stats definitions", count );
- }
-
- // Fill gaps and check integrity
- for (PetLevelInfoMap::iterator itr = petInfo.begin(); itr != petInfo.end(); ++itr)
- {
- PetLevelInfo* pInfo = itr->second;
-
- // fatal error if no level 1 data
- if(!pInfo || pInfo[0].health == 0 )
- {
- sLog.outErrorDb("Creature %u does not have pet stats data for Level 1!",itr->first);
- exit(1);
- }
-
- // fill level gaps
- for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
- {
- if(pInfo[level].health == 0)
- {
- sLog.outErrorDb("Creature %u has no data for Level %i pet stats data, using data of Level %i.",itr->first,level+1, level);
- pInfo[level] = pInfo[level-1];
- }
- }
- }
-}
-
-PetLevelInfo const* ObjectMgr::GetPetLevelInfo(uint32 creature_id, uint32 level) const
-{
- if(level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
-
- PetLevelInfoMap::const_iterator itr = petInfo.find(creature_id);
- if(itr == petInfo.end())
- return NULL;
-
- return &itr->second[level-1]; // data for level 1 stored in [0] array element, ...
-}
-
-void ObjectMgr::LoadPlayerInfo()
-{
- // Load playercreate
- {
- // 0 1 2 3 4 5 6
- QueryResult *result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z FROM playercreateinfo");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create definitions", count );
- sLog.outErrorDb( "Error loading `playercreateinfo` table or empty table.");
- exit(1);
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_race = fields[0].GetUInt32();
- uint32 current_class = fields[1].GetUInt32();
- uint32 mapId = fields[2].GetUInt32();
- uint32 zoneId = fields[3].GetUInt32();
- float positionX = fields[4].GetFloat();
- float positionY = fields[5].GetFloat();
- float positionZ = fields[6].GetFloat();
-
- if(current_race >= MAX_RACES)
- {
- sLog.outErrorDb("Wrong race %u in `playercreateinfo` table, ignoring.",current_race);
- continue;
- }
-
- ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race);
- if(!rEntry)
- {
- sLog.outErrorDb("Wrong race %u in `playercreateinfo` table, ignoring.",current_race);
- continue;
- }
-
- if(current_class >= MAX_CLASSES)
- {
- sLog.outErrorDb("Wrong class %u in `playercreateinfo` table, ignoring.",current_class);
- continue;
- }
-
- if(!sChrClassesStore.LookupEntry(current_class))
- {
- sLog.outErrorDb("Wrong class %u in `playercreateinfo` table, ignoring.",current_class);
- continue;
- }
-
- // accept DB data only for valid position (and non instanceable)
- if( !MapManager::IsValidMapCoord(mapId,positionX,positionY,positionZ) )
- {
- sLog.outErrorDb("Wrong home position for class %u race %u pair in `playercreateinfo` table, ignoring.",current_class,current_race);
- continue;
- }
-
- if( sMapStore.LookupEntry(mapId)->Instanceable() )
- {
- sLog.outErrorDb("Home position in instanceable map for class %u race %u pair in `playercreateinfo` table, ignoring.",current_class,current_race);
- continue;
- }
-
- PlayerInfo* pInfo = &playerInfo[current_race][current_class];
-
- pInfo->mapId = mapId;
- pInfo->zoneId = zoneId;
- pInfo->positionX = positionX;
- pInfo->positionY = positionY;
- pInfo->positionZ = positionZ;
-
- pInfo->displayId_m = rEntry->model_m;
- pInfo->displayId_f = rEntry->model_f;
-
- bar.step();
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create definitions", count );
- }
-
- // Load playercreate items
- {
- // 0 1 2 3
- QueryResult *result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create items", count );
- sLog.outErrorDb( "Error loading `playercreateinfo_item` table or empty table.");
- }
- else
- {
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_race = fields[0].GetUInt32();
- if(current_race >= MAX_RACES)
- {
- sLog.outErrorDb("Wrong race %u in `playercreateinfo_item` table, ignoring.",current_race);
- continue;
- }
-
- uint32 current_class = fields[1].GetUInt32();
- if(current_class >= MAX_CLASSES)
- {
- sLog.outErrorDb("Wrong class %u in `playercreateinfo_item` table, ignoring.",current_class);
- continue;
- }
-
- PlayerInfo* pInfo = &playerInfo[current_race][current_class];
-
- uint32 item_id = fields[2].GetUInt32();
-
- if(!GetItemPrototype(item_id))
- {
- sLog.outErrorDb("Item id %u (race %u class %u) in `playercreateinfo_item` table but not listed in `item_template`, ignoring.",item_id,current_race,current_class);
- continue;
- }
-
- uint32 amount = fields[3].GetUInt32();
-
- if(!amount)
- {
- sLog.outErrorDb("Item id %u (class %u race %u) have amount==0 in `playercreateinfo_item` table, ignoring.",item_id,current_race,current_class);
- continue;
- }
-
- pInfo->item.push_back(PlayerCreateInfoItem( item_id, amount));
-
- bar.step();
- ++count;
- }
- while(result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create items", count );
- }
- }
-
- // Load playercreate spells
- {
-
- QueryResult *result = NULL;
- if(sWorld.getConfig(CONFIG_START_ALL_SPELLS))
- result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell_custom");
- else
- result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create spells", count );
- sLog.outErrorDb( "Error loading player starting spells or empty table.");
- }
- else
- {
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_race = fields[0].GetUInt32();
- if(current_race >= MAX_RACES)
- {
- sLog.outErrorDb("Wrong race %u in `playercreateinfo_spell` table, ignoring.",current_race);
- continue;
- }
-
- uint32 current_class = fields[1].GetUInt32();
- if(current_class >= MAX_CLASSES)
- {
- sLog.outErrorDb("Wrong class %u in `playercreateinfo_spell` table, ignoring.",current_class);
- continue;
- }
-
- PlayerInfo* pInfo = &playerInfo[current_race][current_class];
- pInfo->spell.push_back(CreateSpellPair(fields[2].GetUInt16(), fields[3].GetUInt8()));
-
- bar.step();
- ++count;
- }
- while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create spells", count );
- }
- }
-
- // Load playercreate actions
- {
- // 0 1 2 3 4 5
- QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type, misc FROM playercreateinfo_action");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create actions", count );
- sLog.outErrorDb( "Error loading `playercreateinfo_action` table or empty table.");
- }
- else
- {
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_race = fields[0].GetUInt32();
- if(current_race >= MAX_RACES)
- {
- sLog.outErrorDb("Wrong race %u in `playercreateinfo_action` table, ignoring.",current_race);
- continue;
- }
-
- uint32 current_class = fields[1].GetUInt32();
- if(current_class >= MAX_CLASSES)
- {
- sLog.outErrorDb("Wrong class %u in `playercreateinfo_action` table, ignoring.",current_class);
- continue;
- }
-
- PlayerInfo* pInfo = &playerInfo[current_race][current_class];
- pInfo->action[0].push_back(fields[2].GetUInt16());
- pInfo->action[1].push_back(fields[3].GetUInt16());
- pInfo->action[2].push_back(fields[4].GetUInt16());
- pInfo->action[3].push_back(fields[5].GetUInt16());
-
- bar.step();
- ++count;
- }
- while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u player create actions", count );
- }
- }
-
- // Loading levels data (class only dependent)
- {
- // 0 1 2 3
- QueryResult *result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u level health/mana definitions", count );
- sLog.outErrorDb( "Error loading `player_classlevelstats` table or empty table.");
- exit(1);
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_class = fields[0].GetUInt32();
- if(current_class >= MAX_CLASSES)
- {
- sLog.outErrorDb("Wrong class %u in `player_classlevelstats` table, ignoring.",current_class);
- continue;
- }
-
- uint32 current_level = fields[1].GetUInt32();
- if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- if(current_level > 255) // hardcoded level maximum
- sLog.outErrorDb("Wrong (> 255) level %u in `player_classlevelstats` table, ignoring.",current_level);
- else
- sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_classlevelstats` table, ignoring.",current_level);
- continue;
- }
-
- PlayerClassInfo* pClassInfo = &playerClassInfo[current_class];
-
- if(!pClassInfo->levelInfo)
- pClassInfo->levelInfo = new PlayerClassLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)];
-
- PlayerClassLevelInfo* pClassLevelInfo = &pClassInfo->levelInfo[current_level-1];
-
- pClassLevelInfo->basehealth = fields[2].GetUInt16();
- pClassLevelInfo->basemana = fields[3].GetUInt16();
-
- bar.step();
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u level health/mana definitions", count );
- }
-
- // Fill gaps and check integrity
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- {
- // skip non existed classes
- if(!sChrClassesStore.LookupEntry(class_))
- continue;
-
- PlayerClassInfo* pClassInfo = &playerClassInfo[class_];
-
- // fatal error if no level 1 data
- if(!pClassInfo->levelInfo || pClassInfo->levelInfo[0].basehealth == 0 )
- {
- sLog.outErrorDb("Class %i Level 1 does not have health/mana data!",class_);
- exit(1);
- }
-
- // fill level gaps
- for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
- {
- if(pClassInfo->levelInfo[level].basehealth == 0)
- {
- sLog.outErrorDb("Class %i Level %i does not have health/mana data. Using stats data of level %i.",class_,level+1, level);
- pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level-1];
- }
- }
- }
-
- // Loading levels data (class/race dependent)
- {
- // 0 1 2 3 4 5 6 7
- QueryResult *result = WorldDatabase.Query("SELECT race, class, level, str, agi, sta, inte, spi FROM player_levelstats");
-
- uint32 count = 0;
-
- if (!result)
- {
- barGoLink bar( 1 );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u level stats definitions", count );
- sLog.outErrorDb( "Error loading `player_levelstats` table or empty table.");
- exit(1);
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_race = fields[0].GetUInt32();
- if(current_race >= MAX_RACES)
- {
- sLog.outErrorDb("Wrong race %u in `player_levelstats` table, ignoring.",current_race);
- continue;
- }
-
- uint32 current_class = fields[1].GetUInt32();
- if(current_class >= MAX_CLASSES)
- {
- sLog.outErrorDb("Wrong class %u in `player_levelstats` table, ignoring.",current_class);
- continue;
- }
-
- uint32 current_level = fields[2].GetUInt32();
- if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- if(current_level > 255) // hardcoded level maximum
- sLog.outErrorDb("Wrong (> 255) level %u in `player_levelstats` table, ignoring.",current_level);
- else
- sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_levelstats` table, ignoring.",current_level);
- continue;
- }
-
- PlayerInfo* pInfo = &playerInfo[current_race][current_class];
-
- if(!pInfo->levelInfo)
- pInfo->levelInfo = new PlayerLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)];
-
- PlayerLevelInfo* pLevelInfo = &pInfo->levelInfo[current_level-1];
-
- for (int i = 0; i < MAX_STATS; i++)
- {
- pLevelInfo->stats[i] = fields[i+3].GetUInt8();
- }
-
- bar.step();
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u level stats definitions", count );
- }
-
- // Fill gaps and check integrity
- for (int race = 0; race < MAX_RACES; ++race)
- {
- // skip non existed races
- if(!sChrRacesStore.LookupEntry(race))
- continue;
-
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- {
- // skip non existed classes
- if(!sChrClassesStore.LookupEntry(class_))
- continue;
-
- PlayerInfo* pInfo = &playerInfo[race][class_];
-
- // skip non loaded combinations
- if(!pInfo->displayId_m || !pInfo->displayId_f)
- continue;
-
- // skip expansion races if not playing with expansion
- if (sWorld.getConfig(CONFIG_EXPANSION) < 1 && (race == RACE_BLOODELF || race == RACE_DRAENEI))
- continue;
-
- // skip expansion classes if not playing with expansion
- if (sWorld.getConfig(CONFIG_EXPANSION) < 2 && class_ == CLASS_DEATH_KNIGHT)
- continue;
-
- // fatal error if no level 1 data
- if(!pInfo->levelInfo || pInfo->levelInfo[0].stats[0] == 0 )
- {
- sLog.outErrorDb("Race %i Class %i Level 1 does not have stats data!",race,class_);
- exit(1);
- }
-
- // fill level gaps
- for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
- {
- if(pInfo->levelInfo[level].stats[0] == 0)
- {
- sLog.outErrorDb("Race %i Class %i Level %i does not have stats data. Using stats data of level %i.",race,class_,level+1, level);
- pInfo->levelInfo[level] = pInfo->levelInfo[level-1];
- }
- }
- }
- }
-}
-
-void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint32 level, PlayerClassLevelInfo* info) const
-{
- if(level < 1 || class_ >= MAX_CLASSES)
- return;
-
- PlayerClassInfo const* pInfo = &playerClassInfo[class_];
-
- if(level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
-
- *info = pInfo->levelInfo[level-1];
-}
-
-void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint32 level, PlayerLevelInfo* info) const
-{
- if(level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES)
- return;
-
- PlayerInfo const* pInfo = &playerInfo[race][class_];
- if(pInfo->displayId_m==0 || pInfo->displayId_f==0)
- return;
-
- if(level <= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- *info = pInfo->levelInfo[level-1];
- else
- BuildPlayerLevelInfo(race,class_,level,info);
-}
-
-void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, PlayerLevelInfo* info) const
-{
- // base data (last known level)
- *info = playerInfo[race][_class].levelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)-1];
-
- for(int lvl = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)-1; lvl < level; ++lvl)
- {
- switch(_class)
- {
- case CLASS_WARRIOR:
- info->stats[STAT_STRENGTH] += (lvl > 23 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_STAMINA] += (lvl > 23 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_AGILITY] += (lvl > 36 ? 1: (lvl > 6 && (lvl%2) ? 1: 0));
- info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl%2) ? 1: 0);
- info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl%2) ? 1: 0);
- break;
- case CLASS_PALADIN:
- info->stats[STAT_STRENGTH] += (lvl > 3 ? 1: 0);
- info->stats[STAT_STAMINA] += (lvl > 33 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_AGILITY] += (lvl > 38 ? 1: (lvl > 7 && !(lvl%2) ? 1: 0));
- info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl%2) ? 1: 0);
- info->stats[STAT_SPIRIT] += (lvl > 7 ? 1: 0);
- break;
- case CLASS_HUNTER:
- info->stats[STAT_STRENGTH] += (lvl > 4 ? 1: 0);
- info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0);
- info->stats[STAT_AGILITY] += (lvl > 33 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl%2) ? 1: 0);
- info->stats[STAT_SPIRIT] += (lvl > 38 ? 1: (lvl > 9 && !(lvl%2) ? 1: 0));
- break;
- case CLASS_ROGUE:
- info->stats[STAT_STRENGTH] += (lvl > 5 ? 1: 0);
- info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0);
- info->stats[STAT_AGILITY] += (lvl > 16 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl%2) ? 1: 0);
- info->stats[STAT_SPIRIT] += (lvl > 38 ? 1: (lvl > 9 && !(lvl%2) ? 1: 0));
- break;
- case CLASS_PRIEST:
- info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0);
- info->stats[STAT_STAMINA] += (lvl > 5 ? 1: 0);
- info->stats[STAT_AGILITY] += (lvl > 38 ? 1: (lvl > 8 && (lvl%2) ? 1: 0));
- info->stats[STAT_INTELLECT] += (lvl > 22 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_SPIRIT] += (lvl > 3 ? 1: 0);
- break;
- case CLASS_SHAMAN:
- info->stats[STAT_STRENGTH] += (lvl > 34 ? 1: (lvl > 6 && (lvl%2) ? 1: 0));
- info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0);
- info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl%2) ? 1: 0);
- info->stats[STAT_INTELLECT] += (lvl > 5 ? 1: 0);
- info->stats[STAT_SPIRIT] += (lvl > 4 ? 1: 0);
- break;
- case CLASS_MAGE:
- info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0);
- info->stats[STAT_STAMINA] += (lvl > 5 ? 1: 0);
- info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl%2) ? 1: 0);
- info->stats[STAT_INTELLECT] += (lvl > 24 ? 2: (lvl > 1 ? 1: 0));
- info->stats[STAT_SPIRIT] += (lvl > 33 ? 2: (lvl > 2 ? 1: 0));
- break;
- case CLASS_WARLOCK:
- info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0);
- info->stats[STAT_STAMINA] += (lvl > 38 ? 2: (lvl > 3 ? 1: 0));
- info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl%2) ? 1: 0);
- info->stats[STAT_INTELLECT] += (lvl > 33 ? 2: (lvl > 2 ? 1: 0));
- info->stats[STAT_SPIRIT] += (lvl > 38 ? 2: (lvl > 3 ? 1: 0));
- break;
- case CLASS_DRUID:
- info->stats[STAT_STRENGTH] += (lvl > 38 ? 2: (lvl > 6 && (lvl%2) ? 1: 0));
- info->stats[STAT_STAMINA] += (lvl > 32 ? 2: (lvl > 4 ? 1: 0));
- info->stats[STAT_AGILITY] += (lvl > 38 ? 2: (lvl > 8 && (lvl%2) ? 1: 0));
- info->stats[STAT_INTELLECT] += (lvl > 38 ? 3: (lvl > 4 ? 1: 0));
- info->stats[STAT_SPIRIT] += (lvl > 38 ? 3: (lvl > 5 ? 1: 0));
- }
- }
-}
-
-void ObjectMgr::LoadGuilds()
-{
- Guild *newguild;
- uint32 count = 0;
-
- QueryResult *result = CharacterDatabase.Query( "SELECT guildid FROM guild" );
-
- if( !result )
- {
-
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u guild definitions", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field *fields = result->Fetch();
-
- bar.step();
- ++count;
-
- newguild = new Guild;
- if(!newguild->LoadGuildFromDB(fields[0].GetUInt32()))
- {
- newguild->Disband();
- delete newguild;
- continue;
- }
- AddGuild(newguild);
-
- }while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u guild definitions", count );
-}
-
-void ObjectMgr::LoadArenaTeams()
-{
- uint32 count = 0;
-
- QueryResult *result = CharacterDatabase.Query( "SELECT arenateamid FROM arena_team" );
-
- if( !result )
- {
-
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u arenateam definitions", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field *fields = result->Fetch();
-
- bar.step();
- ++count;
-
- ArenaTeam *newarenateam = new ArenaTeam;
- if(!newarenateam->LoadArenaTeamFromDB(fields[0].GetUInt32()))
- {
- delete newarenateam;
- continue;
- }
- AddArenaTeam(newarenateam);
- }while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u arenateam definitions", count );
-}
-
-void ObjectMgr::LoadGroups()
-{
- // -- loading groups --
- Group *group = NULL;
- uint64 leaderGuid = 0;
- uint32 count = 0;
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- QueryResult *result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u group definitions", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
- Field *fields = result->Fetch();
- ++count;
- leaderGuid = MAKE_NEW_GUID(fields[15].GetUInt32(),0,HIGHGUID_PLAYER);
-
- group = new Group;
- if(!group->LoadGroupFromDB(leaderGuid, result, false))
- {
- group->Disband();
- delete group;
- continue;
- }
- AddGroup(group);
- }while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u group definitions", count );
-
- // -- loading members --
- count = 0;
- group = NULL;
- leaderGuid = 0;
- // 0 1 2 3
- result = CharacterDatabase.Query("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid");
- if(!result)
- {
- barGoLink bar( 1 );
- bar.step();
- }
- else
- {
- barGoLink bar( result->GetRowCount() );
- do
- {
- bar.step();
- Field *fields = result->Fetch();
- count++;
- leaderGuid = MAKE_NEW_GUID(fields[3].GetUInt32(), 0, HIGHGUID_PLAYER);
- if(!group || group->GetLeaderGUID() != leaderGuid)
- {
- group = GetGroupByLeader(leaderGuid);
- if(!group)
- {
- sLog.outErrorDb("Incorrect entry in group_member table : no group with leader %d for member %d!", fields[3].GetUInt32(), fields[0].GetUInt32());
- CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid = '%d'", fields[0].GetUInt32());
- continue;
- }
- }
-
- if(!group->LoadMemberFromDB(fields[0].GetUInt32(), fields[2].GetUInt8(), fields[1].GetBool()))
- {
- sLog.outErrorDb("Incorrect entry in group_member table : member %d cannot be added to player %d's group!", fields[0].GetUInt32(), fields[3].GetUInt32());
- CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid = '%d'", fields[0].GetUInt32());
- }
- }while( result->NextRow() );
- delete result;
- }
-
- // clean groups
- // TODO: maybe delete from the DB before loading in this case
- for(GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end();)
- {
- if((*itr)->GetMembersCount() < 2)
- {
- (*itr)->Disband();
- delete *itr;
- mGroupSet.erase(itr++);
- }
- else
- ++itr;
- }
-
- // -- loading instances --
- count = 0;
- group = NULL;
- leaderGuid = 0;
- result = CharacterDatabase.Query(
- // 0 1 2 3 4 5
- "SELECT leaderGuid, map, instance, permanent, difficulty, resettime, "
- // 6
- "(SELECT COUNT(*) FROM character_instance WHERE guid = leaderGuid AND instance = group_instance.instance AND permanent = 1 LIMIT 1) "
- "FROM group_instance LEFT JOIN instance ON instance = id ORDER BY leaderGuid"
- );
-
- if(!result)
- {
- barGoLink bar( 1 );
- bar.step();
- }
- else
- {
- barGoLink bar( result->GetRowCount() );
- do
- {
- bar.step();
- Field *fields = result->Fetch();
- count++;
- leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
- if(!group || group->GetLeaderGUID() != leaderGuid)
- {
- group = GetGroupByLeader(leaderGuid);
- if(!group)
- {
- sLog.outErrorDb("Incorrect entry in group_instance table : no group with leader %d", fields[0].GetUInt32());
- continue;
- }
- }
-
- InstanceSave *save = sInstanceSaveManager.AddInstanceSave(fields[1].GetUInt32(), fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
- group->BindToInstance(save, fields[3].GetBool(), true);
- }while( result->NextRow() );
- delete result;
- }
-
- sLog.outString();
- sLog.outString( ">> Loaded %u group-instance binds total", count );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u group members total", count );
-}
-
-void ObjectMgr::LoadQuests()
-{
- // For reload case
- for(QuestMap::const_iterator itr=mQuestTemplates.begin(); itr != mQuestTemplates.end(); ++itr)
- delete itr->second;
- mQuestTemplates.clear();
-
- mExclusiveQuestGroups.clear();
-
- // 0 1 2 3 4 5 6 7 8
- QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
- // 9 10 11 12 13 14 15 16
- "RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime,"
- // 17 18 19 20 21 22 23 24 25 26
- "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
- // 27 28 29 30 31 32 33 34 35 36
- "Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
- // 37 38 39 40 41 42 43 44
- "ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4,"
- // 45 46 47 48 49 50 51 52 53 54 54 55
- "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4,"
- // 57 58 59 60 61 62 63 64
- "ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
- // 65 66 67 68
- "ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
- // 69 70 71 72 73 74
- "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
- // 75 76 77 78 79 80
- "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6,"
- // 81 82 83 84 85 86 87 88
- "RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
- // 89 90 91 92 93 94 95 96 97 98
- "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
- // 99 100 101 102 103 104 105 106 107 108 109
- "RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
- // 110 111 112 113 114 115 116 117 118 119
- "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
- // 120 121
- "StartScript, CompleteScript"
- " FROM quest_template");
- if(result == NULL)
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded 0 quests definitions" );
- sLog.outErrorDb("`quest_template` table is empty!");
- return;
- }
-
- // create multimap previous quest for each existed quest
- // some quests can have many previous maps set by NextQuestId in previous quest
- // for example set of race quests can lead to single not race specific quest
- barGoLink bar( result->GetRowCount() );
- do
- {
- bar.step();
- Field *fields = result->Fetch();
-
- Quest * newQuest = new Quest(fields);
- mQuestTemplates[newQuest->GetQuestId()] = newQuest;
- } while( result->NextRow() );
-
- delete result;
-
- // Post processing
- for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); iter++)
- {
- Quest * qinfo = iter->second;
-
- // additional quest integrity checks (GO, creature_template and item_template must be loaded already)
-
- if( qinfo->GetQuestMethod() >= 3 )
- {
- sLog.outErrorDb("Quest %u has `Method` = %u, expected values are 0, 1 or 2.",qinfo->GetQuestId(),qinfo->GetQuestMethod());
- }
-
- if (qinfo->QuestFlags & ~QUEST_TRINITY_FLAGS_DB_ALLOWED)
- {
- sLog.outErrorDb("Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u",
- qinfo->GetQuestId(),qinfo->QuestFlags,QUEST_TRINITY_FLAGS_DB_ALLOWED >> 16);
- qinfo->QuestFlags &= QUEST_TRINITY_FLAGS_DB_ALLOWED;
- }
-
- if(qinfo->QuestFlags & QUEST_FLAGS_DAILY)
- {
- if(!(qinfo->QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE))
- {
- sLog.outErrorDb("Daily Quest %u not marked as repeatable in `SpecialFlags`, added.",qinfo->GetQuestId());
- qinfo->QuestFlags |= QUEST_TRINITY_FLAGS_REPEATABLE;
- }
- }
-
- if(qinfo->QuestFlags & QUEST_FLAGS_AUTO_REWARDED)
- {
- // at auto-reward can be rewarded only RewChoiceItemId[0]
- for(int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
- {
- if(uint32 id = qinfo->RewChoiceItemId[j])
- {
- sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but item from `RewChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_AUTO_REWARDED.",
- qinfo->GetQuestId(),j+1,id,j+1);
- // no changes, quest ignore this data
- }
- }
- }
-
- // client quest log visual (area case)
- if( qinfo->ZoneOrSort > 0 )
- {
- if(!GetAreaEntryByAreaID(qinfo->ZoneOrSort))
- {
- sLog.outErrorDb("Quest %u has `ZoneOrSort` = %u (zone case) but zone with this id does not exist.",
- qinfo->GetQuestId(),qinfo->ZoneOrSort);
- // no changes, quest not dependent from this value but can have problems at client
- }
- }
- // client quest log visual (sort case)
- if( qinfo->ZoneOrSort < 0 )
- {
- QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->ZoneOrSort));
- if( !qSort )
- {
- sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (sort case) but quest sort with this id does not exist.",
- qinfo->GetQuestId(),qinfo->ZoneOrSort);
- // no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
- }
- //check SkillOrClass value (class case).
- if( ClassByQuestSort(-int32(qinfo->ZoneOrSort)) )
- {
- // SkillOrClass should not have class case when class case already set in ZoneOrSort.
- if(qinfo->SkillOrClass < 0)
- {
- sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (class sort case) and `SkillOrClass` = %i (class case), redundant.",
- qinfo->GetQuestId(),qinfo->ZoneOrSort,qinfo->SkillOrClass);
- }
- }
- //check for proper SkillOrClass value (skill case)
- if(int32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
- {
- // skill is positive value in SkillOrClass
- if(qinfo->SkillOrClass != skill_id )
- {
- sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (skill sort case) but `SkillOrClass` does not have a corresponding value (%i).",
- qinfo->GetQuestId(),qinfo->ZoneOrSort,skill_id);
- //override, and force proper value here?
- }
- }
- }
-
- // SkillOrClass (class case)
- if( qinfo->SkillOrClass < 0 )
- {
- if( !sChrClassesStore.LookupEntry(-int32(qinfo->SkillOrClass)) )
- {
- sLog.outErrorDb("Quest %u has `SkillOrClass` = %i (class case) but class (%i) does not exist",
- qinfo->GetQuestId(),qinfo->SkillOrClass,-qinfo->SkillOrClass);
- }
- }
- // SkillOrClass (skill case)
- if( qinfo->SkillOrClass > 0 )
- {
- if( !sSkillLineStore.LookupEntry(qinfo->SkillOrClass) )
- {
- sLog.outErrorDb("Quest %u has `SkillOrClass` = %u (skill case) but skill (%i) does not exist",
- qinfo->GetQuestId(),qinfo->SkillOrClass,qinfo->SkillOrClass);
- }
- }
-
- if( qinfo->RequiredSkillValue )
- {
- if( qinfo->RequiredSkillValue > sWorld.GetConfigMaxSkillValue() )
- {
- sLog.outErrorDb("Quest %u has `RequiredSkillValue` = %u but max possible skill is %u, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RequiredSkillValue,sWorld.GetConfigMaxSkillValue());
- // no changes, quest can't be done for this requirement
- }
-
- if( qinfo->SkillOrClass <= 0 )
- {
- sLog.outErrorDb("Quest %u has `RequiredSkillValue` = %u but `SkillOrClass` = %i (class case), value ignored.",
- qinfo->GetQuestId(),qinfo->RequiredSkillValue,qinfo->SkillOrClass);
- // no changes, quest can't be done for this requirement (fail at wrong skill id)
- }
- }
- // else Skill quests can have 0 skill level, this is ok
-
- if(qinfo->RepObjectiveFaction && !sFactionStore.LookupEntry(qinfo->RepObjectiveFaction))
- {
- sLog.outErrorDb("Quest %u has `RepObjectiveFaction` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RepObjectiveFaction,qinfo->RepObjectiveFaction);
- // no changes, quest can't be done for this requirement
- }
-
- if(qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
- {
- sLog.outErrorDb("Quest %u has `RequiredMinRepFaction` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RequiredMinRepFaction,qinfo->RequiredMinRepFaction);
- // no changes, quest can't be done for this requirement
- }
-
- if(qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction))
- {
- sLog.outErrorDb("Quest %u has `RequiredMaxRepFaction` = %u but faction template %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RequiredMaxRepFaction,qinfo->RequiredMaxRepFaction);
- // no changes, quest can't be done for this requirement
- }
-
- if(qinfo->RequiredMinRepValue && qinfo->RequiredMinRepValue > Player::Reputation_Cap)
- {
- sLog.outErrorDb("Quest %u has `RequiredMinRepValue` = %d but max reputation is %u, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RequiredMinRepValue,Player::Reputation_Cap);
- // no changes, quest can't be done for this requirement
- }
-
- if(qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue)
- {
- sLog.outErrorDb("Quest %u has `RequiredMaxRepValue` = %d and `RequiredMinRepValue` = %d, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RequiredMaxRepValue,qinfo->RequiredMinRepValue);
- // no changes, quest can't be done for this requirement
- }
-
- if(!qinfo->RepObjectiveFaction && qinfo->RepObjectiveValue > 0 )
- {
- sLog.outErrorDb("Quest %u has `RepObjectiveValue` = %d but `RepObjectiveFaction` is 0, value has no effect",
- qinfo->GetQuestId(),qinfo->RepObjectiveValue);
- // warning
- }
-
- if(!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue > 0 )
- {
- sLog.outErrorDb("Quest %u has `RequiredMinRepValue` = %d but `RequiredMinRepFaction` is 0, value has no effect",
- qinfo->GetQuestId(),qinfo->RequiredMinRepValue);
- // warning
- }
-
- if(!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue > 0 )
- {
- sLog.outErrorDb("Quest %u has `RequiredMaxRepValue` = %d but `RequiredMaxRepFaction` is 0, value has no effect",
- qinfo->GetQuestId(),qinfo->RequiredMaxRepValue);
- // warning
- }
-
- if(qinfo->CharTitleId && !sCharTitlesStore.LookupEntry(qinfo->CharTitleId))
- {
- sLog.outErrorDb("Quest %u has `CharTitleId` = %u but CharTitle Id %u does not exist, quest can't be rewarded with title.",
- qinfo->GetQuestId(),qinfo->GetCharTitleId(),qinfo->GetCharTitleId());
- qinfo->CharTitleId = 0;
- // quest can't reward this title
- }
-
- if(qinfo->SrcItemId)
- {
- if(!sItemStorage.LookupEntry<ItemPrototype>(qinfo->SrcItemId))
- {
- sLog.outErrorDb("Quest %u has `SrcItemId` = %u but item with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),qinfo->SrcItemId,qinfo->SrcItemId);
- qinfo->SrcItemId = 0; // quest can't be done for this requirement
- }
- else if(qinfo->SrcItemCount==0)
- {
- sLog.outErrorDb("Quest %u has `SrcItemId` = %u but `SrcItemCount` = 0, set to 1 but need fix in DB.",
- qinfo->GetQuestId(),qinfo->SrcItemId);
- qinfo->SrcItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB
- }
- }
- else if(qinfo->SrcItemCount>0)
- {
- sLog.outErrorDb("Quest %u has `SrcItemId` = 0 but `SrcItemCount` = %u, useless value.",
- qinfo->GetQuestId(),qinfo->SrcItemCount);
- qinfo->SrcItemCount=0; // no quest work changes in fact
- }
-
- if(qinfo->SrcSpell)
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->SrcSpell);
- if(!spellInfo)
- {
- sLog.outErrorDb("Quest %u has `SrcSpell` = %u but spell %u doesn't exist, quest can't be done.",
- qinfo->GetQuestId(),qinfo->SrcSpell,qinfo->SrcSpell);
- qinfo->SrcSpell = 0; // quest can't be done for this requirement
- }
- else if(!SpellMgr::IsSpellValid(spellInfo))
- {
- sLog.outErrorDb("Quest %u has `SrcSpell` = %u but spell %u is broken, quest can't be done.",
- qinfo->GetQuestId(),qinfo->SrcSpell,qinfo->SrcSpell);
- qinfo->SrcSpell = 0; // quest can't be done for this requirement
- }
- }
-
- for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j )
- {
- uint32 id = qinfo->ReqItemId[j];
- if(id)
- {
- if(qinfo->ReqItemCount[j]==0)
- {
- sLog.outErrorDb("Quest %u has `ReqItemId%d` = %u but `ReqItemCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,j+1);
- // no changes, quest can't be done for this requirement
- }
-
- qinfo->SetFlag(QUEST_TRINITY_FLAGS_DELIVER);
-
- if(!sItemStorage.LookupEntry<ItemPrototype>(id))
- {
- sLog.outErrorDb("Quest %u has `ReqItemId%d` = %u but item with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,id);
- qinfo->ReqItemCount[j] = 0; // prevent incorrect work of quest
- }
- }
- else if(qinfo->ReqItemCount[j]>0)
- {
- sLog.outErrorDb("Quest %u has `ReqItemId%d` = 0 but `ReqItemCount%d` = %u, quest can't be done.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->ReqItemCount[j]);
- qinfo->ReqItemCount[j] = 0; // prevent incorrect work of quest
- }
- }
-
- for(int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j )
- {
- uint32 id = qinfo->ReqSourceId[j];
- if(id)
- {
- if(!sItemStorage.LookupEntry<ItemPrototype>(id))
- {
- sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but item with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,id);
- // no changes, quest can't be done for this requirement
- }
-
- if(!qinfo->ReqSourceCount[j])
- {
- sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but `ReqSourceCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,j+1);
- qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest
- }
-
- if(!qinfo->ReqSourceRef[j])
- {
- sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but `ReqSourceRef%d` = 0, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,j+1);
- qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest
- }
- }
- else
- {
- if(qinfo->ReqSourceCount[j]>0)
- {
- sLog.outErrorDb("Quest %u has `ReqSourceId%d` = 0 but `ReqSourceCount%d` = %u.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->ReqSourceCount[j]);
- // no changes, quest ignore this data
- }
-
- if(qinfo->ReqSourceRef[j]>0)
- {
- sLog.outErrorDb("Quest %u has `ReqSourceId%d` = 0 but `ReqSourceRef%d` = %u.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->ReqSourceRef[j]);
- // no changes, quest ignore this data
- }
- }
- }
-
- for(int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j )
- {
- uint32 ref = qinfo->ReqSourceRef[j];
- if(ref)
- {
- if(ref > QUEST_OBJECTIVES_COUNT)
- {
- sLog.outErrorDb("Quest %u has `ReqSourceRef%d` = %u but max value in `ReqSourceRef%d` is %u, quest can't be done.",
- qinfo->GetQuestId(),j+1,ref,j+1,QUEST_OBJECTIVES_COUNT);
- // no changes, quest can't be done for this requirement
- }
- else
- if(!qinfo->ReqItemId[ref-1] && !qinfo->ReqSpell[ref-1])
- {
- sLog.outErrorDb("Quest %u has `ReqSourceRef%d` = %u but `ReqItemId%u` = 0 and `ReqSpellCast%u` = 0, quest can't be done.",
- qinfo->GetQuestId(),j+1,ref,ref,ref);
- // no changes, quest can't be done for this requirement
- }
- else if(qinfo->ReqItemId[ref-1] && qinfo->ReqSpell[ref-1])
- {
- sLog.outErrorDb("Quest %u has `ReqItemId%u` = %u and `ReqSpellCast%u` = %u, quest can't have both fields <> 0, then can't be done.",
- qinfo->GetQuestId(),ref,qinfo->ReqItemId[ref-1],ref,qinfo->ReqSpell[ref-1]);
- // no changes, quest can't be done for this requirement
- qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest
- }
- }
- }
-
- for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j )
- {
- uint32 id = qinfo->ReqSpell[j];
- if(id)
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
- if(!spellInfo)
- {
- sLog.outErrorDb("Quest %u has `ReqSpellCast%d` = %u but spell %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,id);
- // no changes, quest can't be done for this requirement
- }
-
- if(!qinfo->ReqCreatureOrGOId[j])
- {
- bool found = false;
- for(int k = 0; k < 3; ++k)
- {
- if( spellInfo->Effect[k]==SPELL_EFFECT_QUEST_COMPLETE && uint32(spellInfo->EffectMiscValue[k])==qinfo->QuestId ||
- spellInfo->Effect[k]==SPELL_EFFECT_SEND_EVENT)
- {
- found = true;
- break;
- }
- }
-
- if(found)
- {
- if(!qinfo->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
- {
- sLog.outErrorDb("Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT for quest %u and ReqCreatureOrGOId%d = 0, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Quest flags or ReqCreatureOrGOId%d must be fixed, quest modified to enable objective.",spellInfo->Id,qinfo->QuestId,j+1,j+1);
-
- // this will prevent quest completing without objective
- const_cast<Quest*>(qinfo)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
- }
- }
- else
- {
- sLog.outErrorDb("Quest %u has `ReqSpellCast%d` = %u and ReqCreatureOrGOId%d = 0 but spell %u does not have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT effect for this quest, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,j+1,id);
- // no changes, quest can't be done for this requirement
- }
- }
- }
- }
-
- for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j )
- {
- int32 id = qinfo->ReqCreatureOrGOId[j];
- if(id < 0 && !sGOStorage.LookupEntry<GameObjectInfo>(-id))
- {
- sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %i but gameobject %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,uint32(-id));
- qinfo->ReqCreatureOrGOId[j] = 0; // quest can't be done for this requirement
- }
-
- if(id > 0 && !sCreatureStorage.LookupEntry<CreatureInfo>(id))
- {
- sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %i but creature with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,uint32(id));
- qinfo->ReqCreatureOrGOId[j] = 0; // quest can't be done for this requirement
- }
-
- if(id)
- {
- // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
-
- qinfo->SetFlag(QUEST_TRINITY_FLAGS_KILL_OR_CAST | QUEST_TRINITY_FLAGS_SPEAKTO);
-
- if(!qinfo->ReqCreatureOrGOCount[j])
- {
- sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %u but `ReqCreatureOrGOCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,j+1);
- // no changes, quest can be incorrectly done, but we already report this
- }
- }
- else if(qinfo->ReqCreatureOrGOCount[j]>0)
- {
- sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = 0 but `ReqCreatureOrGOCount%d` = %u.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->ReqCreatureOrGOCount[j]);
- // no changes, quest ignore this data
- }
- }
-
- for(int j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j )
- {
- uint32 id = qinfo->RewChoiceItemId[j];
- if(id)
- {
- if(!sItemStorage.LookupEntry<ItemPrototype>(id))
- {
- sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.",
- qinfo->GetQuestId(),j+1,id,id);
- qinfo->RewChoiceItemId[j] = 0; // no changes, quest will not reward this
- }
-
- if(!qinfo->RewChoiceItemCount[j])
- {
- sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but `RewChoiceItemCount%d` = 0, quest can't be done.",
- qinfo->GetQuestId(),j+1,id,j+1);
- // no changes, quest can't be done
- }
- }
- else if(qinfo->RewChoiceItemCount[j]>0)
- {
- sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = 0 but `RewChoiceItemCount%d` = %u.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->RewChoiceItemCount[j]);
- // no changes, quest ignore this data
- }
- }
-
- for(int j = 0; j < QUEST_REWARDS_COUNT; ++j )
- {
- uint32 id = qinfo->RewItemId[j];
- if(id)
- {
- if(!sItemStorage.LookupEntry<ItemPrototype>(id))
- {
- sLog.outErrorDb("Quest %u has `RewItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.",
- qinfo->GetQuestId(),j+1,id,id);
- qinfo->RewItemId[j] = 0; // no changes, quest will not reward this item
- }
-
- if(!qinfo->RewItemCount[j])
- {
- sLog.outErrorDb("Quest %u has `RewItemId%d` = %u but `RewItemCount%d` = 0, quest will not reward this item.",
- qinfo->GetQuestId(),j+1,id,j+1);
- // no changes
- }
- }
- else if(qinfo->RewItemCount[j]>0)
- {
- sLog.outErrorDb("Quest %u has `RewItemId%d` = 0 but `RewItemCount%d` = %u.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->RewItemCount[j]);
- // no changes, quest ignore this data
- }
- }
-
- for(int j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
- {
- if(qinfo->RewRepFaction[j])
- {
- if(!qinfo->RewRepValue[j])
- {
- sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but `RewRepValue%d` = 0, quest will not reward this reputation.",
- qinfo->GetQuestId(),j+1,qinfo->RewRepValue[j],j+1);
- // no changes
- }
-
- if(!sFactionStore.LookupEntry(qinfo->RewRepFaction[j]))
- {
- sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but raw faction (faction.dbc) %u does not exist, quest will not reward reputation for this faction.",
- qinfo->GetQuestId(),j+1,qinfo->RewRepFaction[j] ,qinfo->RewRepFaction[j] );
- qinfo->RewRepFaction[j] = 0; // quest will not reward this
- }
- }
- else if(qinfo->RewRepValue[j]!=0)
- {
- sLog.outErrorDb("Quest %u has `RewRepFaction%d` = 0 but `RewRepValue%d` = %u.",
- qinfo->GetQuestId(),j+1,j+1,qinfo->RewRepValue[j]);
- // no changes, quest ignore this data
- }
- }
-
- if(qinfo->RewSpell)
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpell);
-
- if(!spellInfo)
- {
- sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u does not exist, spell removed as display reward.",
- qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
- qinfo->RewSpell = 0; // no spell reward will display for this quest
- }
-
- else if(!SpellMgr::IsSpellValid(spellInfo))
- {
- sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is broken, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
- qinfo->RewSpell = 0; // no spell reward will display for this quest
- }
-
- }
-
- if(qinfo->RewSpellCast)
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpellCast);
-
- if(!spellInfo)
- {
- sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.",
- qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
- qinfo->RewSpellCast = 0; // no spell will be casted on player
- }
-
- else if(!SpellMgr::IsSpellValid(spellInfo))
- {
- sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u is broken, quest can't be done.",
- qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
- qinfo->RewSpellCast = 0; // no spell will be casted on player
- }
-
- }
-
- if(qinfo->RewMailTemplateId)
- {
- if(!sMailTemplateStore.LookupEntry(qinfo->RewMailTemplateId))
- {
- sLog.outErrorDb("Quest %u has `RewMailTemplateId` = %u but mail template %u does not exist, quest will not have a mail reward.",
- qinfo->GetQuestId(),qinfo->RewMailTemplateId,qinfo->RewMailTemplateId);
- qinfo->RewMailTemplateId = 0; // no mail will send to player
- qinfo->RewMailDelaySecs = 0; // no mail will send to player
- }
- }
-
- if(qinfo->NextQuestInChain)
- {
- if(mQuestTemplates.find(qinfo->NextQuestInChain) == mQuestTemplates.end())
- {
- sLog.outErrorDb("Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.",
- qinfo->GetQuestId(),qinfo->NextQuestInChain ,qinfo->NextQuestInChain );
- qinfo->NextQuestInChain = 0;
- }
- else
- mQuestTemplates[qinfo->NextQuestInChain]->prevChainQuests.push_back(qinfo->GetQuestId());
- }
-
- // fill additional data stores
- if(qinfo->PrevQuestId)
- {
- if (mQuestTemplates.find(abs(qinfo->GetPrevQuestId())) == mQuestTemplates.end())
- {
- sLog.outErrorDb("Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
- }
- else
- {
- qinfo->prevQuests.push_back(qinfo->PrevQuestId);
- }
- }
-
- if(qinfo->NextQuestId)
- {
- if (mQuestTemplates.find(abs(qinfo->GetNextQuestId())) == mQuestTemplates.end())
- {
- sLog.outErrorDb("Quest %d has NextQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
- }
- else
- {
- int32 signedQuestId = qinfo->NextQuestId < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId());
- mQuestTemplates[abs(qinfo->GetNextQuestId())]->prevQuests.push_back(signedQuestId);
- }
- }
-
- if(qinfo->ExclusiveGroup)
- mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
- if(qinfo->LimitTime)
- qinfo->SetFlag(QUEST_TRINITY_FLAGS_TIMED);
- }
-
- // check QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
- for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
- {
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
- if(!spellInfo)
- continue;
-
- for(int j = 0; j < 3; ++j)
- {
- if(spellInfo->Effect[j] != SPELL_EFFECT_QUEST_COMPLETE)
- continue;
-
- uint32 quest_id = spellInfo->EffectMiscValue[j];
-
- Quest const* quest = GetQuestTemplate(quest_id);
-
- // some quest referenced in spells not exist (outdated spells)
- if(!quest)
- continue;
-
- if(!quest->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
- {
- sLog.outErrorDb("Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE for quest %u , but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Quest flags must be fixed, quest modified to enable objective.",spellInfo->Id,quest_id);
-
- // this will prevent quest completing without objective
- const_cast<Quest*>(quest)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
- }
- }
- }
-
- sLog.outString();
- sLog.outString( ">> Loaded %u quests definitions", mQuestTemplates.size() );
-}
-
-void ObjectMgr::LoadQuestLocales()
-{
- mQuestLocaleMap.clear();
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,"
- "Title_loc1,Details_loc1,Objectives_loc1,OfferRewardText_loc1,RequestItemsText_loc1,EndText_loc1,ObjectiveText1_loc1,ObjectiveText2_loc1,ObjectiveText3_loc1,ObjectiveText4_loc1,"
- "Title_loc2,Details_loc2,Objectives_loc2,OfferRewardText_loc2,RequestItemsText_loc2,EndText_loc2,ObjectiveText1_loc2,ObjectiveText2_loc2,ObjectiveText3_loc2,ObjectiveText4_loc2,"
- "Title_loc3,Details_loc3,Objectives_loc3,OfferRewardText_loc3,RequestItemsText_loc3,EndText_loc3,ObjectiveText1_loc3,ObjectiveText2_loc3,ObjectiveText3_loc3,ObjectiveText4_loc3,"
- "Title_loc4,Details_loc4,Objectives_loc4,OfferRewardText_loc4,RequestItemsText_loc4,EndText_loc4,ObjectiveText1_loc4,ObjectiveText2_loc4,ObjectiveText3_loc4,ObjectiveText4_loc4,"
- "Title_loc5,Details_loc5,Objectives_loc5,OfferRewardText_loc5,RequestItemsText_loc5,EndText_loc5,ObjectiveText1_loc5,ObjectiveText2_loc5,ObjectiveText3_loc5,ObjectiveText4_loc5,"
- "Title_loc6,Details_loc6,Objectives_loc6,OfferRewardText_loc6,RequestItemsText_loc6,EndText_loc6,ObjectiveText1_loc6,ObjectiveText2_loc6,ObjectiveText3_loc6,ObjectiveText4_loc6,"
- "Title_loc7,Details_loc7,Objectives_loc7,OfferRewardText_loc7,RequestItemsText_loc7,EndText_loc7,ObjectiveText1_loc7,ObjectiveText2_loc7,ObjectiveText3_loc7,ObjectiveText4_loc7,"
- "Title_loc8,Details_loc8,Objectives_loc8,OfferRewardText_loc8,RequestItemsText_loc8,EndText_loc8,ObjectiveText1_loc8,ObjectiveText2_loc8,ObjectiveText3_loc8,ObjectiveText4_loc8"
- " FROM locales_quest"
- );
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_quest` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- QuestLocale& data = mQuestLocaleMap[entry];
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[1+10*(i-1)].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Title.size() <= idx)
- data.Title.resize(idx+1);
-
- data.Title[idx] = str;
- }
- }
- str = fields[1+10*(i-1)+1].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Details.size() <= idx)
- data.Details.resize(idx+1);
-
- data.Details[idx] = str;
- }
- }
- str = fields[1+10*(i-1)+2].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Objectives.size() <= idx)
- data.Objectives.resize(idx+1);
-
- data.Objectives[idx] = str;
- }
- }
- str = fields[1+10*(i-1)+3].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.OfferRewardText.size() <= idx)
- data.OfferRewardText.resize(idx+1);
-
- data.OfferRewardText[idx] = str;
- }
- }
- str = fields[1+10*(i-1)+4].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.RequestItemsText.size() <= idx)
- data.RequestItemsText.resize(idx+1);
-
- data.RequestItemsText[idx] = str;
- }
- }
- str = fields[1+10*(i-1)+5].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.EndText.size() <= idx)
- data.EndText.resize(idx+1);
-
- data.EndText[idx] = str;
- }
- }
- for(int k = 0; k < 4; ++k)
- {
- str = fields[1+10*(i-1)+6+k].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.ObjectiveText[k].size() <= idx)
- data.ObjectiveText[k].resize(idx+1);
-
- data.ObjectiveText[k][idx] = str;
- }
- }
- }
- }
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u Quest locale strings", mQuestLocaleMap.size() );
-}
-
-void ObjectMgr::LoadPetCreateSpells()
-{
- QueryResult *result = WorldDatabase.Query("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell");
- if(!result)
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded 0 pet create spells" );
- sLog.outErrorDb("`petcreateinfo_spell` table is empty!");
- return;
- }
-
- uint32 count = 0;
-
- barGoLink bar( result->GetRowCount() );
-
- mPetCreateSpell.clear();
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 creature_id = fields[0].GetUInt32();
-
- if(!creature_id || !sCreatureStorage.LookupEntry<CreatureInfo>(creature_id))
- continue;
-
- PetCreateSpellEntry PetCreateSpell;
- for(int i = 0; i < 4; i++)
- {
- PetCreateSpell.spellid[i] = fields[i + 1].GetUInt32();
-
- if(PetCreateSpell.spellid[i] && !sSpellStore.LookupEntry(PetCreateSpell.spellid[i]))
- sLog.outErrorDb("Spell %u listed in `petcreateinfo_spell` does not exist",PetCreateSpell.spellid[i]);
- }
-
- mPetCreateSpell[creature_id] = PetCreateSpell;
-
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u pet create spells", count );
-}
-
-void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
-{
- if(sWorld.IsScriptScheduled()) // function don't must be called in time scripts use.
- return;
-
- sLog.outString( "%s :", tablename);
-
- scripts.clear(); // need for reload support
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,datatext, x, y, z, o FROM %s", tablename );
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u script definitions", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
-
- Field *fields = result->Fetch();
- ScriptInfo tmp;
- tmp.id = fields[0].GetUInt32();
- tmp.delay = fields[1].GetUInt32();
- tmp.command = fields[2].GetUInt32();
- tmp.datalong = fields[3].GetUInt32();
- tmp.datalong2 = fields[4].GetUInt32();
- tmp.datatext = fields[5].GetCppString();
- tmp.x = fields[6].GetFloat();
- tmp.y = fields[7].GetFloat();
- tmp.z = fields[8].GetFloat();
- tmp.o = fields[9].GetFloat();
-
- // generic command args check
- switch(tmp.command)
- {
- case SCRIPT_COMMAND_TALK:
- {
- if(tmp.datalong > 3)
- {
- sLog.outErrorDb("Table `%s` has invalid talk type (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.datalong,tmp.id);
- continue;
- }
- break;
- }
-
- case SCRIPT_COMMAND_TELEPORT_TO:
- {
- if(!sMapStore.LookupEntry(tmp.datalong))
- {
- sLog.outErrorDb("Table `%s` has invalid map (Id: %u) in SCRIPT_COMMAND_TELEPORT_TO for script id %u",tablename,tmp.datalong,tmp.id);
- continue;
- }
-
- if(!Trinity::IsValidMapCoord(tmp.x,tmp.y,tmp.z,tmp.o))
- {
- sLog.outErrorDb("Table `%s` has invalid coordinates (X: %f Y: %f) in SCRIPT_COMMAND_TELEPORT_TO for script id %u",tablename,tmp.x,tmp.y,tmp.id);
- continue;
- }
- break;
- }
-
- case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
- {
- if(!Trinity::IsValidMapCoord(tmp.x,tmp.y,tmp.z,tmp.o))
- {
- sLog.outErrorDb("Table `%s` has invalid coordinates (X: %f Y: %f) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u",tablename,tmp.x,tmp.y,tmp.id);
- continue;
- }
-
- if(!GetCreatureTemplate(tmp.datalong))
- {
- sLog.outErrorDb("Table `%s` has invalid creature (Entry: %u) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u",tablename,tmp.datalong,tmp.id);
- continue;
- }
- break;
- }
-
- case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
- {
- GameObjectData const* data = GetGOData(tmp.datalong);
- if(!data)
- {
- sLog.outErrorDb("Table `%s` has invalid gameobject (GUID: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,tmp.datalong,tmp.id);
- continue;
- }
-
- GameObjectInfo const* info = GetGameObjectInfo(data->id);
- if(!info)
- {
- sLog.outErrorDb("Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,tmp.datalong,data->id,tmp.id);
- continue;
- }
-
- if( info->type==GAMEOBJECT_TYPE_FISHINGNODE ||
- info->type==GAMEOBJECT_TYPE_FISHINGHOLE ||
- info->type==GAMEOBJECT_TYPE_DOOR ||
- info->type==GAMEOBJECT_TYPE_BUTTON ||
- info->type==GAMEOBJECT_TYPE_TRAP )
- {
- sLog.outErrorDb("Table `%s` have gameobject type (%u) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,info->id,tmp.id);
- continue;
- }
- break;
- }
- case SCRIPT_COMMAND_OPEN_DOOR:
- case SCRIPT_COMMAND_CLOSE_DOOR:
- {
- GameObjectData const* data = GetGOData(tmp.datalong);
- if(!data)
- {
- sLog.outErrorDb("Table `%s` has invalid gameobject (GUID: %u) in %s for script id %u",tablename,tmp.datalong,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id);
- continue;
- }
-
- GameObjectInfo const* info = GetGameObjectInfo(data->id);
- if(!info)
- {
- sLog.outErrorDb("Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in %s for script id %u",tablename,tmp.datalong,data->id,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id);
- continue;
- }
-
- if( info->type!=GAMEOBJECT_TYPE_DOOR)
- {
- sLog.outErrorDb("Table `%s` has gameobject type (%u) non supported by command %s for script id %u",tablename,info->id,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id);
- continue;
- }
-
- break;
- }
- case SCRIPT_COMMAND_QUEST_EXPLORED:
- {
- Quest const* quest = GetQuestTemplate(tmp.datalong);
- if(!quest)
- {
- sLog.outErrorDb("Table `%s` has invalid quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",tablename,tmp.datalong,tmp.id);
- continue;
- }
-
- if(!quest->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
- {
- sLog.outErrorDb("Table `%s` has quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT in quest flags. Script command or quest flags wrong. Quest modified to require objective.",tablename,tmp.datalong,tmp.id);
-
- // this will prevent quest completing without objective
- const_cast<Quest*>(quest)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
-
- // continue; - quest objective requirement set and command can be allowed
- }
-
- if(float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE)
- {
- sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",
- tablename,tmp.datalong2,tmp.id);
- continue;
- }
-
- if(tmp.datalong2 && float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE)
- {
- sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, max distance is %f or 0 for disable distance check",
- tablename,tmp.datalong2,tmp.id,DEFAULT_VISIBILITY_DISTANCE);
- continue;
- }
-
- if(tmp.datalong2 && float(tmp.datalong2) < INTERACTION_DISTANCE)
- {
- sLog.outErrorDb("Table `%s` has too small distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, min distance is %f or 0 for disable distance check",
- tablename,tmp.datalong2,tmp.id,INTERACTION_DISTANCE);
- continue;
- }
-
- break;
- }
-
- case SCRIPT_COMMAND_REMOVE_AURA:
- case SCRIPT_COMMAND_CAST_SPELL:
- {
- if(!sSpellStore.LookupEntry(tmp.datalong))
- {
- sLog.outErrorDb("Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_REMOVE_AURA or SCRIPT_COMMAND_CAST_SPELL for script id %u",
- tablename,tmp.datalong,tmp.id);
- continue;
- }
- break;
- }
- }
-
- if (scripts.find(tmp.id) == scripts.end())
- {
- ScriptMap emptyMap;
- scripts[tmp.id] = emptyMap;
- }
- scripts[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
-
- ++count;
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u script definitions", count );
-}
-
-void ObjectMgr::LoadGameObjectScripts()
-{
- LoadScripts(sGameObjectScripts, "gameobject_scripts");
-
- // check ids
- for(ScriptMapMap::const_iterator itr = sGameObjectScripts.begin(); itr != sGameObjectScripts.end(); ++itr)
- {
- if(!GetGOData(itr->first))
- sLog.outErrorDb("Table `gameobject_scripts` has not existing gameobject (GUID: %u) as script id",itr->first);
- }
-}
-
-void ObjectMgr::LoadQuestEndScripts()
-{
- LoadScripts(sQuestEndScripts, "quest_end_scripts");
-
- // check ids
- for(ScriptMapMap::const_iterator itr = sQuestEndScripts.begin(); itr != sQuestEndScripts.end(); ++itr)
- {
- if(!GetQuestTemplate(itr->first))
- sLog.outErrorDb("Table `quest_end_scripts` has not existing quest (Id: %u) as script id",itr->first);
- }
-}
-
-void ObjectMgr::LoadQuestStartScripts()
-{
- LoadScripts(sQuestStartScripts,"quest_start_scripts");
-
- // check ids
- for(ScriptMapMap::const_iterator itr = sQuestStartScripts.begin(); itr != sQuestStartScripts.end(); ++itr)
- {
- if(!GetQuestTemplate(itr->first))
- sLog.outErrorDb("Table `quest_start_scripts` has not existing quest (Id: %u) as script id",itr->first);
- }
-}
-
-void ObjectMgr::LoadSpellScripts()
-{
- LoadScripts(sSpellScripts, "spell_scripts");
-
- // check ids
- for(ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
- {
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first);
-
- if(!spellInfo)
- {
- sLog.outErrorDb("Table `spell_scripts` has not existing spell (Id: %u) as script id",itr->first);
- continue;
- }
-
- //check for correct spellEffect
- bool found = false;
- for(int i=0; i<3; ++i)
- {
- // skip empty effects
- if( !spellInfo->Effect[i] )
- continue;
-
- if( spellInfo->Effect[i] == SPELL_EFFECT_SCRIPT_EFFECT )
- {
- found = true;
- break;
- }
- }
-
- if(!found)
- sLog.outErrorDb("Table `spell_scripts` has unsupported spell (Id: %u) without SPELL_EFFECT_SCRIPT_EFFECT (%u) spell effect",itr->first,SPELL_EFFECT_SCRIPT_EFFECT);
- }
-}
-
-void ObjectMgr::LoadEventScripts()
-{
- LoadScripts(sEventScripts, "event_scripts");
-
- std::set<uint32> evt_scripts;
- // Load all possible script entries from gameobjects
- for(uint32 i = 1; i < sGOStorage.MaxEntry; ++i)
- {
- GameObjectInfo const * goInfo = sGOStorage.LookupEntry<GameObjectInfo>(i);
- if (goInfo)
- {
- switch(goInfo->type)
- {
- case GAMEOBJECT_TYPE_GOOBER:
- if(goInfo->goober.eventId)
- evt_scripts.insert(goInfo->goober.eventId);
- break;
- case GAMEOBJECT_TYPE_CHEST:
- if(goInfo->chest.eventId)
- evt_scripts.insert(goInfo->chest.eventId);
- break;
- default:
- break;
- }
- }
- }
- // Load all possible script entries from spells
- for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
- {
- SpellEntry const * spell = sSpellStore.LookupEntry(i);
- if (spell)
- {
- for(int j=0; j<3; ++j)
- {
- if( spell->Effect[j] == SPELL_EFFECT_SEND_EVENT )
- {
- if (spell->EffectMiscValue[j])
- evt_scripts.insert(spell->EffectMiscValue[j]);
- }
- }
- }
- }
- // Then check if all scripts are in above list of possible script entries
- for(ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
- {
- std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
- if (itr2 == evt_scripts.end())
- sLog.outErrorDb("Table `event_scripts` has script (Id: %u) not referring to any gameobject_template type 10 data2 field or type 3 data6 field or any spell effect %u", itr->first, SPELL_EFFECT_SEND_EVENT);
- }
-}
-
-void ObjectMgr::LoadItemTexts()
-{
- QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text");
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u item pages", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- Field* fields;
- do
- {
- bar.step();
-
- fields = result->Fetch();
-
- mItemTexts[ fields[0].GetUInt32() ] = fields[1].GetCppString();
-
- ++count;
-
- } while ( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u item texts", count );
-}
-
-void ObjectMgr::LoadPageTexts()
-{
- sPageTextStore.Free(); // for reload case
-
- sPageTextStore.Load();
- sLog.outString( ">> Loaded %u page texts", sPageTextStore.RecordCount );
- sLog.outString();
-
- for(uint32 i = 1; i < sPageTextStore.MaxEntry; ++i)
- {
- // check data correctness
- PageText const* page = sPageTextStore.LookupEntry<PageText>(i);
- if(!page)
- continue;
-
- if(page->Next_Page && !sPageTextStore.LookupEntry<PageText>(page->Next_Page))
- {
- sLog.outErrorDb("Page text (Id: %u) has not existing next page (Id:%u)", i,page->Next_Page);
- continue;
- }
-
- // detect circular reference
- std::set<uint32> checkedPages;
- for(PageText const* pageItr = page; pageItr; pageItr = sPageTextStore.LookupEntry<PageText>(pageItr->Next_Page))
- {
- if(!pageItr->Next_Page)
- break;
- checkedPages.insert(pageItr->Page_ID);
- if(checkedPages.find(pageItr->Next_Page)!=checkedPages.end())
- {
- std::ostringstream ss;
- ss<< "The text page(s) ";
- for (std::set<uint32>::iterator itr= checkedPages.begin();itr!=checkedPages.end(); itr++)
- ss << *itr << " ";
- ss << "create(s) a circular reference, which can cause the server to freeze. Changing Next_Page of page "
- << pageItr->Page_ID <<" to 0";
- sLog.outErrorDb(ss.str().c_str());
- const_cast<PageText*>(pageItr)->Next_Page = 0;
- break;
- }
- }
- }
-}
-
-void ObjectMgr::LoadPageTextLocales()
-{
- mPageTextLocaleMap.clear();
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 PageText locale strings. DB table `locales_page_text` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- PageTextLocale& data = mPageTextLocaleMap[entry];
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[i].GetCppString();
- if(str.empty())
- continue;
-
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Text.size() <= idx)
- data.Text.resize(idx+1);
-
- data.Text[idx] = str;
- }
- }
-
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u PageText locale strings", mPageTextLocaleMap.size() );
-}
-
-void ObjectMgr::LoadInstanceTemplate()
-{
- sInstanceTemplate.Load();
-
- for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
- {
- InstanceTemplate* temp = (InstanceTemplate*)GetInstanceTemplate(i);
- if(!temp) continue;
- const MapEntry* entry = sMapStore.LookupEntry(temp->map);
- if(!entry)
- {
- sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: bad mapid %d for template!", temp->map);
- continue;
- }
- else if(!entry->HasResetTime())
- continue;
-
- if(temp->reset_delay == 0)
- {
- // use defaults from the DBC
- if(entry->SupportsHeroicMode())
- {
- temp->reset_delay = entry->resetTimeHeroic / DAY;
- }
- else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
- {
- temp->reset_delay = entry->resetTimeRaid / DAY;
- }
- }
-
- // the reset_delay must be at least one day
- temp->reset_delay = std::max((uint32)1, (uint32)(temp->reset_delay * sWorld.getRate(RATE_INSTANCE_RESET_TIME)));
- }
-
- sLog.outString( ">> Loaded %u Instance Template definitions", sInstanceTemplate.RecordCount );
- sLog.outString();
-}
-
-void ObjectMgr::AddGossipText(GossipText *pGText)
-{
- ASSERT( pGText->Text_ID );
- ASSERT( mGossipText.find(pGText->Text_ID) == mGossipText.end() );
- mGossipText[pGText->Text_ID] = pGText;
-}
-
-GossipText *ObjectMgr::GetGossipText(uint32 Text_ID)
-{
- GossipTextMap::const_iterator itr;
- for (itr = mGossipText.begin(); itr != mGossipText.end(); itr++)
- {
- if(itr->second->Text_ID == Text_ID)
- return itr->second;
- }
- return NULL;
-}
-
-void ObjectMgr::LoadGossipText()
-{
- GossipText *pGText;
- QueryResult *result = WorldDatabase.Query( "SELECT * FROM npc_text" );
-
- int count = 0;
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u npc texts", count );
- return;
- }
-
- int cic;
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- cic = 0;
-
- Field *fields = result->Fetch();
-
- bar.step();
-
- pGText = new GossipText;
- pGText->Text_ID = fields[cic++].GetUInt32();
-
- for (int i=0; i< 8; i++)
- {
- pGText->Options[i].Text_0 = fields[cic++].GetCppString();
- pGText->Options[i].Text_1 = fields[cic++].GetCppString();
-
- pGText->Options[i].Language = fields[cic++].GetUInt32();
- pGText->Options[i].Probability = fields[cic++].GetFloat();
-
- pGText->Options[i].Emotes[0]._Delay = fields[cic++].GetUInt32();
- pGText->Options[i].Emotes[0]._Emote = fields[cic++].GetUInt32();
-
- pGText->Options[i].Emotes[1]._Delay = fields[cic++].GetUInt32();
- pGText->Options[i].Emotes[1]._Emote = fields[cic++].GetUInt32();
-
- pGText->Options[i].Emotes[2]._Delay = fields[cic++].GetUInt32();
- pGText->Options[i].Emotes[2]._Emote = fields[cic++].GetUInt32();
- }
-
- if ( !pGText->Text_ID ) continue;
- AddGossipText( pGText );
-
- } while( result->NextRow() );
-
- sLog.outString();
- sLog.outString( ">> Loaded %u npc texts", count );
- delete result;
-}
-
-void ObjectMgr::LoadNpcTextLocales()
-{
- mNpcTextLocaleMap.clear();
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,"
- "Text0_0_loc1,Text0_1_loc1,Text1_0_loc1,Text1_1_loc1,Text2_0_loc1,Text2_1_loc1,Text3_0_loc1,Text3_1_loc1,Text4_0_loc1,Text4_1_loc1,Text5_0_loc1,Text5_1_loc1,Text6_0_loc1,Text6_1_loc1,Text7_0_loc1,Text7_1_loc1,"
- "Text0_0_loc2,Text0_1_loc2,Text1_0_loc2,Text1_1_loc2,Text2_0_loc2,Text2_1_loc2,Text3_0_loc2,Text3_1_loc1,Text4_0_loc2,Text4_1_loc2,Text5_0_loc2,Text5_1_loc2,Text6_0_loc2,Text6_1_loc2,Text7_0_loc2,Text7_1_loc2,"
- "Text0_0_loc3,Text0_1_loc3,Text1_0_loc3,Text1_1_loc3,Text2_0_loc3,Text2_1_loc3,Text3_0_loc3,Text3_1_loc1,Text4_0_loc3,Text4_1_loc3,Text5_0_loc3,Text5_1_loc3,Text6_0_loc3,Text6_1_loc3,Text7_0_loc3,Text7_1_loc3,"
- "Text0_0_loc4,Text0_1_loc4,Text1_0_loc4,Text1_1_loc4,Text2_0_loc4,Text2_1_loc4,Text3_0_loc4,Text3_1_loc1,Text4_0_loc4,Text4_1_loc4,Text5_0_loc4,Text5_1_loc4,Text6_0_loc4,Text6_1_loc4,Text7_0_loc4,Text7_1_loc4,"
- "Text0_0_loc5,Text0_1_loc5,Text1_0_loc5,Text1_1_loc5,Text2_0_loc5,Text2_1_loc5,Text3_0_loc5,Text3_1_loc1,Text4_0_loc5,Text4_1_loc5,Text5_0_loc5,Text5_1_loc5,Text6_0_loc5,Text6_1_loc5,Text7_0_loc5,Text7_1_loc5,"
- "Text0_0_loc6,Text0_1_loc6,Text1_0_loc6,Text1_1_loc6,Text2_0_loc6,Text2_1_loc6,Text3_0_loc6,Text3_1_loc1,Text4_0_loc6,Text4_1_loc6,Text5_0_loc6,Text5_1_loc6,Text6_0_loc6,Text6_1_loc6,Text7_0_loc6,Text7_1_loc6,"
- "Text0_0_loc7,Text0_1_loc7,Text1_0_loc7,Text1_1_loc7,Text2_0_loc7,Text2_1_loc7,Text3_0_loc7,Text3_1_loc1,Text4_0_loc7,Text4_1_loc7,Text5_0_loc7,Text5_1_loc7,Text6_0_loc7,Text6_1_loc7,Text7_0_loc7,Text7_1_loc7, "
- "Text0_0_loc8,Text0_1_loc8,Text1_0_loc8,Text1_1_loc8,Text2_0_loc8,Text2_1_loc8,Text3_0_loc8,Text3_1_loc1,Text4_0_loc8,Text4_1_loc8,Text5_0_loc8,Text5_1_loc8,Text6_0_loc8,Text6_1_loc8,Text7_0_loc8,Text7_1_loc8 "
- " FROM locales_npc_text");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_npc_text` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- NpcTextLocale& data = mNpcTextLocaleMap[entry];
-
- for(int i=1; i<MAX_LOCALE; ++i)
- {
- for(int j=0; j<8; ++j)
- {
- std::string str0 = fields[1+8*2*(i-1)+2*j].GetCppString();
- if(!str0.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Text_0[j].size() <= idx)
- data.Text_0[j].resize(idx+1);
-
- data.Text_0[j][idx] = str0;
- }
- }
- std::string str1 = fields[1+8*2*(i-1)+2*j+1].GetCppString();
- if(!str1.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Text_1[j].size() <= idx)
- data.Text_1[j].resize(idx+1);
-
- data.Text_1[j][idx] = str1;
- }
- }
- }
- }
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u NpcText locale strings", mNpcTextLocaleMap.size() );
-}
-
-//not very fast function but it is called only once a day, or on starting-up
-void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
-{
- time_t basetime = time(NULL);
- sLog.outDebug("Returning mails current time: hour: %d, minute: %d, second: %d ", localtime(&basetime)->tm_hour, localtime(&basetime)->tm_min, localtime(&basetime)->tm_sec);
- //delete all old mails without item and without body immediately, if starting server
- if (!serverUp)
- CharacterDatabase.PExecute("DELETE FROM mail WHERE expire_time < '" I64FMTD "' AND has_items = '0' AND itemTextId = 0", (uint64)basetime);
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" I64FMTD "'", (uint64)basetime);
- if ( !result )
- return; // any mails need to be returned or deleted
- Field *fields;
- //std::ostringstream delitems, delmails; //will be here for optimization
- //bool deletemail = false, deleteitem = false;
- //delitems << "DELETE FROM item_instance WHERE guid IN ( ";
- //delmails << "DELETE FROM mail WHERE id IN ( "
- do
- {
- fields = result->Fetch();
- Mail *m = new Mail;
- m->messageID = fields[0].GetUInt32();
- m->messageType = fields[1].GetUInt8();
- m->sender = fields[2].GetUInt32();
- m->receiver = fields[3].GetUInt32();
- m->itemTextId = fields[4].GetUInt32();
- bool has_items = fields[5].GetBool();
- m->expire_time = (time_t)fields[6].GetUInt64();
- m->deliver_time = 0;
- m->COD = fields[7].GetUInt32();
- m->checked = fields[8].GetUInt32();
- m->mailTemplateId = fields[9].GetInt16();
-
- Player *pl = 0;
- if (serverUp)
- pl = GetPlayer((uint64)m->receiver);
- if (pl && pl->m_mailsLoaded)
- { //this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail
- //his in mailbox and he has already listed his mails )
- delete m;
- continue;
- }
- //delete or return mail:
- if (has_items)
- {
- QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", m->messageID);
- if(resultItems)
- {
- do
- {
- Field *fields2 = resultItems->Fetch();
-
- uint32 item_guid_low = fields2[0].GetUInt32();
- uint32 item_template = fields2[1].GetUInt32();
-
- m->AddItem(item_guid_low, item_template);
- }
- while (resultItems->NextRow());
-
- delete resultItems;
- }
- //if it is mail from AH, it shouldn't be returned, but deleted
- if (m->messageType != MAIL_NORMAL || (m->checked & (MAIL_CHECK_MASK_AUCTION | MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED)))
- {
- // mail open and then not returned
- for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
- }
- else
- {
- //mail will be returned:
- CharacterDatabase.PExecute("UPDATE mail SET sender = '%u', receiver = '%u', expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',cod = '0', checked = '%u' WHERE id = '%u'", m->receiver, m->sender, (uint64)(basetime + 30*DAY), (uint64)basetime, MAIL_CHECK_MASK_RETURNED, m->messageID);
- delete m;
- continue;
- }
- }
-
- if (m->itemTextId)
- CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId);
-
- //deletemail = true;
- //delmails << m->messageID << ", ";
- CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
- delete m;
- } while (result->NextRow());
- delete result;
-}
-
-void ObjectMgr::LoadQuestAreaTriggers()
-{
- mQuestAreaTriggerMap.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query( "SELECT id,quest FROM areatrigger_involvedrelation" );
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u quest trigger points", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 trigger_ID = fields[0].GetUInt32();
- uint32 quest_ID = fields[1].GetUInt32();
-
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(trigger_ID);
- if(!atEntry)
- {
- sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",trigger_ID);
- continue;
- }
-
- Quest const* quest = GetQuestTemplate(quest_ID);
-
- if(!quest)
- {
- sLog.outErrorDb("Table `areatrigger_involvedrelation` has record (id: %u) for not existing quest %u",trigger_ID,quest_ID);
- continue;
- }
-
- if(!quest->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
- {
- sLog.outErrorDb("Table `areatrigger_involvedrelation` has record (id: %u) for not quest %u, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Trigger or quest flags must be fixed, quest modified to require objective.",trigger_ID,quest_ID);
-
- // this will prevent quest completing without objective
- const_cast<Quest*>(quest)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
-
- // continue; - quest modified to required objective and trigger can be allowed.
- }
-
- mQuestAreaTriggerMap[trigger_ID] = quest_ID;
-
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u quest trigger points", count );
-}
-
-void ObjectMgr::LoadTavernAreaTriggers()
-{
- mTavernAreaTriggerSet.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query("SELECT id FROM areatrigger_tavern");
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u tavern triggers", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 Trigger_ID = fields[0].GetUInt32();
-
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
- if(!atEntry)
- {
- sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
- continue;
- }
-
- mTavernAreaTriggerSet.insert(Trigger_ID);
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u tavern triggers", count );
-}
-
-void ObjectMgr::LoadAreaTriggerScripts()
-{
- mAreaTriggerScripts.clear(); // need for reload case
- QueryResult *result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u areatrigger scripts", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 Trigger_ID = fields[0].GetUInt32();
- std::string scriptName = fields[1].GetCppString();
-
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
- if(!atEntry)
- {
- sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
- continue;
- }
- mAreaTriggerScripts[Trigger_ID] = scriptName;
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u areatrigger scripts", count );
-}
-uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid )
-{
- bool found = false;
- float dist;
- uint32 id = 0;
-
- for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
- {
- TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
- if(node && node->map_id == mapid)
- {
- float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
- if(found)
- {
- if(dist2 < dist)
- {
- dist = dist2;
- id = i;
- }
- }
- else
- {
- found = true;
- dist = dist2;
- id = i;
- }
- }
- }
-
- return id;
-}
-
-void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost)
-{
- TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
- if(src_i==sTaxiPathSetBySource.end())
- {
- path = 0;
- cost = 0;
- return;
- }
-
- TaxiPathSetForSource& pathSet = src_i->second;
-
- TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
- if(dest_i==pathSet.end())
- {
- path = 0;
- cost = 0;
- return;
- }
-
- cost = dest_i->second.price;
- path = dest_i->second.ID;
-}
-
-uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )
-{
- uint32 mount_entry = 0;
- uint32 mount_id = 0;
-
- TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
- if (node)
- {
- if (team == ALLIANCE) mount_entry = node->alliance_mount_type;
- else mount_entry = node->horde_mount_type;
-
- CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry);
- if (cinfo)
- {
- if(! (mount_id = cinfo->GetRandomValidModelId()))
- {
- sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry);
- return false;
- }
- }
- }
-
- CreatureModelInfo const *minfo = GetCreatureModelInfo(mount_id);
- if(!minfo)
- {
- sLog.outErrorDb("Taxi mount (Entry: %u) for taxi node (Id: %u) for team %u has model %u not found in table `creature_model_info`, can't load. ",
- mount_entry,id,team,mount_id);
-
- return false;
- }
- if(minfo->modelid_other_gender!=0)
- mount_id = urand(0,1) ? mount_id : minfo->modelid_other_gender;
-
- return mount_id;
-}
-
-void ObjectMgr::GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds)
-{
- if(path >= sTaxiPathNodesByPath.size())
- return;
-
- TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path];
-
- pathnodes.Resize(nodeList.size());
- mapIds.resize(nodeList.size());
-
- for(size_t i = 0; i < nodeList.size(); ++i)
- {
- pathnodes[ i ].x = nodeList[i].x;
- pathnodes[ i ].y = nodeList[i].y;
- pathnodes[ i ].z = nodeList[i].z;
-
- mapIds[i] = nodeList[i].mapid;
- }
-}
-
-void ObjectMgr::GetTransportPathNodes( uint32 path, TransportPath &pathnodes )
-{
- if(path >= sTaxiPathNodesByPath.size())
- return;
-
- TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path];
-
- pathnodes.Resize(nodeList.size());
-
- for(size_t i = 0; i < nodeList.size(); ++i)
- {
- pathnodes[ i ].mapid = nodeList[i].mapid;
- pathnodes[ i ].x = nodeList[i].x;
- pathnodes[ i ].y = nodeList[i].y;
- pathnodes[ i ].z = nodeList[i].z;
- pathnodes[ i ].actionFlag = nodeList[i].actionFlag;
- pathnodes[ i ].delay = nodeList[i].delay;
- }
-}
-
-void ObjectMgr::LoadGraveyardZones()
-{
- mGraveYardMap.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query("SELECT id,ghost_zone,faction FROM game_graveyard_zone");
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u graveyard-zone links", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 safeLocId = fields[0].GetUInt32();
- uint32 zoneId = fields[1].GetUInt32();
- uint32 team = fields[2].GetUInt32();
-
- WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(safeLocId);
- if(!entry)
- {
- sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped.",safeLocId);
- continue;
- }
-
- AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
- if(!areaEntry)
- {
- sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing zone id (%u), skipped.",zoneId);
- continue;
- }
-
- if(areaEntry->zone != 0)
- {
- sLog.outErrorDb("Table `game_graveyard_zone` has record subzone id (%u) instead of zone, skipped.",zoneId);
- continue;
- }
-
- if(team!=0 && team!=HORDE && team!=ALLIANCE)
- {
- sLog.outErrorDb("Table `game_graveyard_zone` has record for non player faction (%u), skipped.",team);
- continue;
- }
-
- if(!AddGraveYardLink(safeLocId,zoneId,team,false))
- sLog.outErrorDb("Table `game_graveyard_zone` has a duplicate record for Graveyard (ID: %u) and Zone (ID: %u), skipped.",safeLocId,zoneId);
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u graveyard-zone links", count );
-}
-
-WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team)
-{
- // search for zone associated closest graveyard
- uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y);
-
- // Simulate std. algorithm:
- // found some graveyard associated to (ghost_zone,ghost_map)
- //
- // if mapId == graveyard.mapId (ghost in plain zone or city or battleground) and search graveyard at same map
- // then check faction
- // if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated
- // then check faction
- GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId);
- GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId);
- if(graveLow==graveUp)
- {
- sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team);
- return NULL;
- }
-
- // at corpse map
- bool foundNear = false;
- float distNear;
- WorldSafeLocsEntry const* entryNear = NULL;
-
- // at entrance map for corpse map
- bool foundEntr = false;
- float distEntr;
- WorldSafeLocsEntry const* entryEntr = NULL;
-
- // some where other
- WorldSafeLocsEntry const* entryFar = NULL;
-
- MapEntry const* mapEntry = sMapStore.LookupEntry(MapId);
-
- for(GraveYardMap::const_iterator itr = graveLow; itr != graveUp; ++itr)
- {
- GraveYardData const& data = itr->second;
-
- WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(data.safeLocId);
- if(!entry)
- {
- sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped.",data.safeLocId);
- continue;
- }
-
- // skip enemy faction graveyard
- // team == 0 case can be at call from .neargrave
- if(data.team != 0 && team != 0 && data.team != team)
- continue;
-
- // find now nearest graveyard at other map
- if(MapId != entry->map_id)
- {
- // if find graveyard at different map from where entrance placed (or no entrance data), use any first
- if (!mapEntry || mapEntry->entrance_map < 0 || mapEntry->entrance_map != entry->map_id ||
- mapEntry->entrance_x == 0 && mapEntry->entrance_y == 0)
- {
- // not have any corrdinates for check distance anyway
- entryFar = entry;
- continue;
- }
-
- // at entrance map calculate distance (2D);
- float dist2 = (entry->x - mapEntry->entrance_x)*(entry->x - mapEntry->entrance_x)
- +(entry->y - mapEntry->entrance_y)*(entry->y - mapEntry->entrance_y);
- if(foundEntr)
- {
- if(dist2 < distEntr)
- {
- distEntr = dist2;
- entryEntr = entry;
- }
- }
- else
- {
- foundEntr = true;
- distEntr = dist2;
- entryEntr = entry;
- }
- }
- // find now nearest graveyard at same map
- else
- {
- float dist2 = (entry->x - x)*(entry->x - x)+(entry->y - y)*(entry->y - y)+(entry->z - z)*(entry->z - z);
- if(foundNear)
- {
- if(dist2 < distNear)
- {
- distNear = dist2;
- entryNear = entry;
- }
- }
- else
- {
- foundNear = true;
- distNear = dist2;
- entryNear = entry;
- }
- }
- }
-
- // find now nearest graveyard at same map
- if(entryNear)
- return entryNear;
-
- if(entryEntr)
- return entryEntr;
-
- return entryFar;
-}
-
-GraveYardData const* ObjectMgr::FindGraveYardData(uint32 id, uint32 zoneId)
-{
- GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId);
- GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId);
-
- for(GraveYardMap::const_iterator itr = graveLow; itr != graveUp; ++itr)
- {
- if(itr->second.safeLocId==id)
- return &itr->second;
- }
-
- return NULL;
-}
-
-bool ObjectMgr::AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inDB)
-{
- if(FindGraveYardData(id,zoneId))
- return false;
-
- // add link to loaded data
- GraveYardData data;
- data.safeLocId = id;
- data.team = team;
-
- mGraveYardMap.insert(GraveYardMap::value_type(zoneId,data));
-
- // add link to DB
- if(inDB)
- {
- WorldDatabase.PExecuteLog("INSERT INTO game_graveyard_zone ( id,ghost_zone,faction) "
- "VALUES ('%u', '%u','%u')",id,zoneId,team);
- }
-
- return true;
-}
-
-void ObjectMgr::RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inDB)
-{
- GraveYardMap::iterator graveLow = mGraveYardMap.lower_bound(zoneId);
- GraveYardMap::iterator graveUp = mGraveYardMap.upper_bound(zoneId);
- if(graveLow==graveUp)
- {
- //sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team);
- return;
- }
-
- bool found = false;
-
- GraveYardMap::iterator itr;
-
- for(itr = graveLow; itr != graveUp; ++itr)
- {
- GraveYardData & data = itr->second;
-
- // skip not matching safezone id
- if(data.safeLocId != id)
- continue;
-
- // skip enemy faction graveyard at same map (normal area, city, or battleground)
- // team == 0 case can be at call from .neargrave
- if(data.team != 0 && team != 0 && data.team != team)
- continue;
-
- found = true;
- break;
- }
-
- // no match, return
- if(!found)
- return;
-
- // remove from links
- mGraveYardMap.erase(itr);
-
- // remove link from DB
- if(inDB)
- {
- WorldDatabase.PExecute("DELETE FROM game_graveyard_zone WHERE id = '%u' AND ghost_zone = '%u' AND faction = '%u'",id,zoneId,team);
- }
-
- return;
-}
-
-
-void ObjectMgr::LoadAreaTriggerTeleports()
-{
- mAreaTriggers.clear(); // need for reload case
-
- uint32 count = 0;
-
- // 0 1 2 3 4 5 6 7 8 9 10 11 12
- QueryResult *result = WorldDatabase.Query("SELECT id, required_level, required_item, required_item2, heroic_key, heroic_key2, required_quest_done, required_failed_text, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
- if( !result )
- {
-
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u area trigger teleport definitions", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- Field *fields = result->Fetch();
-
- bar.step();
-
- ++count;
-
- uint32 Trigger_ID = fields[0].GetUInt32();
-
- AreaTrigger at;
-
- at.requiredLevel = fields[1].GetUInt8();
- at.requiredItem = fields[2].GetUInt32();
- at.requiredItem2 = fields[3].GetUInt32();
- at.heroicKey = fields[4].GetUInt32();
- at.heroicKey2 = fields[5].GetUInt32();
- at.requiredQuest = fields[6].GetUInt32();
- at.requiredFailedText = fields[7].GetCppString();
- at.target_mapId = fields[8].GetUInt32();
- at.target_X = fields[9].GetFloat();
- at.target_Y = fields[10].GetFloat();
- at.target_Z = fields[11].GetFloat();
- at.target_Orientation = fields[12].GetFloat();
-
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
- if(!atEntry)
- {
- sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
- continue;
- }
-
- if(at.requiredItem)
- {
- ItemPrototype const *pProto = GetItemPrototype(at.requiredItem);
- if(!pProto)
- {
- sLog.outError("Key item %u does not exist for trigger %u, removing key requirement.", at.requiredItem, Trigger_ID);
- at.requiredItem = 0;
- }
- }
- if(at.requiredItem2)
- {
- ItemPrototype const *pProto = GetItemPrototype(at.requiredItem2);
- if(!pProto)
- {
- sLog.outError("Second item %u not exist for trigger %u, remove key requirement.", at.requiredItem2, Trigger_ID);
- at.requiredItem2 = 0;
- }
- }
-
- if(at.heroicKey)
- {
- ItemPrototype const *pProto = GetItemPrototype(at.heroicKey);
- if(!pProto)
- {
- sLog.outError("Heroic key item %u not exist for trigger %u, remove key requirement.", at.heroicKey, Trigger_ID);
- at.heroicKey = 0;
- }
- }
-
- if(at.heroicKey2)
- {
- ItemPrototype const *pProto = GetItemPrototype(at.heroicKey2);
- if(!pProto)
- {
- sLog.outError("Heroic second key item %u not exist for trigger %u, remove key requirement.", at.heroicKey2, Trigger_ID);
- at.heroicKey2 = 0;
- }
- }
-
- if(at.requiredQuest)
- {
- if(!mQuestTemplates[at.requiredQuest])
- {
- sLog.outErrorDb("Required Quest %u not exist for trigger %u, remove quest done requirement.",at.requiredQuest,Trigger_ID);
- at.requiredQuest = 0;
- }
- }
-
- MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
- if(!mapEntry)
- {
- sLog.outErrorDb("Area trigger (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.",Trigger_ID,at.target_mapId);
- continue;
- }
-
- if(at.target_X==0 && at.target_Y==0 && at.target_Z==0)
- {
- sLog.outErrorDb("Area trigger (ID:%u) target coordinates not provided.",Trigger_ID);
- continue;
- }
-
- mAreaTriggers[Trigger_ID] = at;
-
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u area trigger teleport definitions", count );
-}
-
-AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
-{
- const MapEntry *mapEntry = sMapStore.LookupEntry(Map);
- if(!mapEntry) return NULL;
- for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); itr++)
- {
- if(itr->second.target_mapId == mapEntry->entrance_map)
- {
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
- if(atEntry && atEntry->mapid == Map)
- return &itr->second;
- }
- }
- return NULL;
-}
-
-void ObjectMgr::SetHighestGuids()
-{
- QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" );
- if( result )
- {
- m_hiCharGuid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
-
- result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" );
- if( result )
- {
- m_hiCreatureGuid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
-
- result = CharacterDatabase.Query( "SELECT MAX(id) FROM character_pet" );
- if( result )
- {
- m_hiPetGuid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
-
- result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );
- if( result )
- {
- m_hiItemGuid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
-
- // Cleanup other tables from not existed guids (>=m_hiItemGuid)
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_hiItemGuid);
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_hiItemGuid);
- CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_hiItemGuid);
- CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_hiItemGuid);
-
- result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" );
- if( result )
- {
- m_hiGoGuid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
-
- result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" );
- if( result )
- {
- m_auctionid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
- else
- {
- m_auctionid = 0;
- }
- result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" );
- if( result )
- {
- m_mailid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
- else
- {
- m_mailid = 0;
- }
- result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" );
- if( result )
- {
- m_ItemTextId = (*result)[0].GetUInt32();
-
- delete result;
- }
- else
- m_ItemTextId = 0;
-
- result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" );
- if( result )
- {
- m_hiCorpseGuid = (*result)[0].GetUInt32()+1;
-
- delete result;
- }
-}
-
-uint32 ObjectMgr::GenerateAuctionID()
-{
- ++m_auctionid;
- if(m_auctionid>=0xFFFFFFFF)
- {
- sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_auctionid;
-}
-
-uint32 ObjectMgr::GenerateMailID()
-{
- ++m_mailid;
- if(m_mailid>=0xFFFFFFFF)
- {
- sLog.outError("Mail ids overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_mailid;
-}
-
-uint32 ObjectMgr::GenerateItemTextID()
-{
- ++m_ItemTextId;
- if(m_ItemTextId>=0xFFFFFFFF)
- {
- sLog.outError("Item text ids overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_ItemTextId;
-}
-
-uint32 ObjectMgr::CreateItemText(std::string text)
-{
- uint32 newItemTextId = GenerateItemTextID();
- //insert new itempage to container
- mItemTexts[ newItemTextId ] = text;
- //save new itempage
- CharacterDatabase.escape_string(text);
- //any Delete query needed, itemTextId is maximum of all ids
- std::ostringstream query;
- query << "INSERT INTO item_text (id,text) VALUES ( '" << newItemTextId << "', '" << text << "')";
- CharacterDatabase.Execute(query.str().c_str()); //needs to be run this way, because mail body may be more than 1024 characters
- return newItemTextId;
-}
-
-uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
-{
- switch(guidhigh)
- {
- case HIGHGUID_ITEM:
- ++m_hiItemGuid;
- if(m_hiItemGuid>=0xFFFFFFFF)
- {
- sLog.outError("Item guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiItemGuid;
- case HIGHGUID_UNIT:
- ++m_hiCreatureGuid;
- if(m_hiCreatureGuid>=0x00FFFFFF)
- {
- sLog.outError("Creature guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiCreatureGuid;
- case HIGHGUID_PET:
- ++m_hiPetGuid;
- if(m_hiPetGuid>=0x00FFFFFF)
- {
- sLog.outError("Pet guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiPetGuid;
- case HIGHGUID_PLAYER:
- ++m_hiCharGuid;
- if(m_hiCharGuid>=0xFFFFFFFF)
- {
- sLog.outError("Players guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiCharGuid;
- case HIGHGUID_GAMEOBJECT:
- ++m_hiGoGuid;
- if(m_hiGoGuid>=0x00FFFFFF)
- {
- sLog.outError("Gameobject guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiGoGuid;
- case HIGHGUID_CORPSE:
- ++m_hiCorpseGuid;
- if(m_hiCorpseGuid>=0xFFFFFFFF)
- {
- sLog.outError("Corpse guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiCorpseGuid;
- case HIGHGUID_DYNAMICOBJECT:
- ++m_hiDoGuid;
- if(m_hiDoGuid>=0xFFFFFFFF)
- {
- sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
- sWorld.m_stopEvent = true;
- }
- return m_hiDoGuid;
- default:
- ASSERT(0);
- }
-
- ASSERT(0);
- return 0;
-}
-
-void ObjectMgr::LoadGameObjectLocales()
-{
- mGameObjectLocaleMap.clear();
-
- QueryResult *result = WorldDatabase.Query("SELECT entry,"
- "name_loc1,name_loc2,name_loc3,name_loc4,name_loc5,name_loc6,name_loc7,name_loc8,"
- "castbarcaption_loc1,castbarcaption_loc2,castbarcaption_loc3,castbarcaption_loc4,"
- "castbarcaption_loc5,castbarcaption_loc6,castbarcaption_loc7,castbarcaption_loc8 FROM locales_gameobject");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- sLog.outString(">> Loaded 0 gameobject locale strings. DB table `locales_gameobject` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 entry = fields[0].GetUInt32();
-
- GameObjectLocale& data = mGameObjectLocaleMap[entry];
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[i].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.Name.size() <= idx)
- data.Name.resize(idx+1);
-
- data.Name[idx] = str;
- }
- }
- }
-
- for(int i = MAX_LOCALE; i < MAX_LOCALE*2-1; ++i)
- {
- std::string str = fields[i].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- if(data.CastBarCaption.size() <= idx)
- data.CastBarCaption.resize(idx+1);
-
- data.CastBarCaption[idx] = str;
- }
- }
- }
-
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u gameobject locale strings", mGameObjectLocaleMap.size() );
-}
-
-void ObjectMgr::LoadGameobjectInfo()
-{
- sGOStorage.Load();
-
- // some checks
- for(uint32 id = 1; id < sGOStorage.MaxEntry; id++)
- {
- GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
- if(!goInfo)
- continue;
-
- switch(goInfo->type)
- {
- case GAMEOBJECT_TYPE_DOOR: //0
- {
- if(goInfo->door.lockId)
- {
- if(!sLockStore.LookupEntry(goInfo->door.lockId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but lock (Id: %u) not found.",
- id,goInfo->type,goInfo->door.lockId,goInfo->door.lockId);
- }
- break;
- }
- case GAMEOBJECT_TYPE_BUTTON: //1
- {
- if(goInfo->button.lockId)
- {
- if(!sLockStore.LookupEntry(goInfo->button.lockId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but lock (Id: %u) not found.",
- id,goInfo->type,goInfo->button.lockId,goInfo->button.lockId);
- }
- break;
- }
- case GAMEOBJECT_TYPE_CHEST: //3
- {
- if(goInfo->chest.lockId)
- {
- if(!sLockStore.LookupEntry(goInfo->chest.lockId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but lock (Id: %u) not found.",
- id,goInfo->type,goInfo->chest.lockId,goInfo->chest.lockId);
- }
- if(goInfo->chest.linkedTrapId) // linked trap
- {
- if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(goInfo->chest.linkedTrapId))
- {
- if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
- id,goInfo->type,goInfo->chest.linkedTrapId,goInfo->chest.linkedTrapId,GAMEOBJECT_TYPE_TRAP);
- }
- /* disable check for while
- else
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
- id,goInfo->type,goInfo->chest.linkedTrapId,goInfo->chest.linkedTrapId);
- */
- }
- break;
- }
- case GAMEOBJECT_TYPE_TRAP: //6
- {
- /* disable check for while
- if(goInfo->trap.spellId) // spell
- {
- if(!sSpellStore.LookupEntry(goInfo->trap.spellId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data3=%u but Spell (Entry %u) not exist.",
- id,goInfo->type,goInfo->trap.spellId,goInfo->trap.spellId);
- }
- */
- break;
- }
- case GAMEOBJECT_TYPE_CHAIR: //7
- if(goInfo->chair.height > 2)
- {
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but correct chair height in range 0..2.",
- id,goInfo->type,goInfo->chair.height);
-
- // prevent client and server unexpected work
- const_cast<GameObjectInfo*>(goInfo)->chair.height = 0;
- }
- break;
- case GAMEOBJECT_TYPE_SPELL_FOCUS: //8
- {
- if(goInfo->spellFocus.focusId)
- {
- if(!sSpellFocusObjectStore.LookupEntry(goInfo->spellFocus.focusId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but SpellFocus (Id: %u) not exist.",
- id,goInfo->type,goInfo->spellFocus.focusId,goInfo->spellFocus.focusId);
- }
-
- if(goInfo->spellFocus.linkedTrapId) // linked trap
- {
- if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(goInfo->spellFocus.linkedTrapId))
- {
- if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
- id,goInfo->type,goInfo->spellFocus.linkedTrapId,goInfo->spellFocus.linkedTrapId,GAMEOBJECT_TYPE_TRAP);
- }
- /* disable check for while
- else
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
- id,goInfo->type,goInfo->spellFocus.linkedTrapId,goInfo->spellFocus.linkedTrapId);
- */
- }
- break;
- }
- case GAMEOBJECT_TYPE_GOOBER: //10
- {
- if(goInfo->goober.pageId) // pageId
- {
- if(!sPageTextStore.LookupEntry<PageText>(goInfo->goober.pageId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but PageText (Entry %u) not exist.",
- id,goInfo->type,goInfo->goober.pageId,goInfo->goober.pageId);
- }
- /* disable check for while
- if(goInfo->goober.spellId) // spell
- {
- if(!sSpellStore.LookupEntry(goInfo->goober.spellId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but Spell (Entry %u) not exist.",
- id,goInfo->type,goInfo->goober.spellId,goInfo->goober.spellId);
- }
- */
- if(goInfo->goober.linkedTrapId) // linked trap
- {
- if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(goInfo->goober.linkedTrapId))
- {
- if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data12=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
- id,goInfo->type,goInfo->goober.linkedTrapId,goInfo->goober.linkedTrapId,GAMEOBJECT_TYPE_TRAP);
- }
- /* disable check for while
- else
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data12=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
- id,goInfo->type,goInfo->goober.linkedTrapId,goInfo->goober.linkedTrapId);
- */
- }
- break;
- }
- case GAMEOBJECT_TYPE_MO_TRANSPORT: //15
- {
- if(goInfo->moTransport.taxiPathId)
- {
- if(goInfo->moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[goInfo->moTransport.taxiPathId].empty())
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but TaxiPath (Id: %u) not exist.",
- id,goInfo->type,goInfo->moTransport.taxiPathId,goInfo->moTransport.taxiPathId);
- }
- break;
- }
- case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18
- {
- /* disabled
- if(goInfo->summoningRitual.spellId)
- {
- if(!sSpellStore.LookupEntry(goInfo->summoningRitual.spellId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but Spell (Entry %u) not exist.",
- id,goInfo->type,goInfo->summoningRitual.spellId,goInfo->summoningRitual.spellId);
- }
- */
- break;
- }
- case GAMEOBJECT_TYPE_SPELLCASTER: //22
- {
- if(goInfo->spellcaster.spellId) // spell
- {
- if(!sSpellStore.LookupEntry(goInfo->spellcaster.spellId))
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data3=%u but Spell (Entry %u) not exist.",
- id,goInfo->type,goInfo->spellcaster.spellId,goInfo->spellcaster.spellId);
- }
- break;
- }
- }
- }
-
- sLog.outString( ">> Loaded %u game object templates", sGOStorage.RecordCount );
- sLog.outString();
-}
-
-void ObjectMgr::LoadExplorationBaseXP()
-{
- uint32 count = 0;
- QueryResult *result = WorldDatabase.Query("SELECT level,basexp FROM exploration_basexp");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u BaseXP definitions", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
-
- Field *fields = result->Fetch();
- uint32 level = fields[0].GetUInt32();
- uint32 basexp = fields[1].GetUInt32();
- mBaseXPTable[level] = basexp;
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u BaseXP definitions", count );
-}
-
-uint32 ObjectMgr::GetBaseXP(uint32 level)
-{
- return mBaseXPTable[level] ? mBaseXPTable[level] : 0;
-}
-
-void ObjectMgr::LoadPetNames()
-{
- uint32 count = 0;
- QueryResult *result = WorldDatabase.Query("SELECT word,entry,half FROM pet_name_generation");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u pet name parts", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
-
- Field *fields = result->Fetch();
- std::string word = fields[0].GetString();
- uint32 entry = fields[1].GetUInt32();
- bool half = fields[2].GetBool();
- if(half)
- PetHalfName1[entry].push_back(word);
- else
- PetHalfName0[entry].push_back(word);
- ++count;
- }
- while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u pet name parts", count );
-}
-
-void ObjectMgr::LoadPetNumber()
-{
- QueryResult* result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
- if(result)
- {
- Field *fields = result->Fetch();
- m_hiPetNumber = fields[0].GetUInt32()+1;
- delete result;
- }
-
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded the max pet number: %d", m_hiPetNumber-1);
-}
-
-std::string ObjectMgr::GeneratePetName(uint32 entry)
-{
- std::vector<std::string> & list0 = PetHalfName0[entry];
- std::vector<std::string> & list1 = PetHalfName1[entry];
-
- if(list0.empty() || list1.empty())
- {
- CreatureInfo const *cinfo = GetCreatureTemplate(entry);
- char* petname = GetPetName(cinfo->family, sWorld.GetDefaultDbcLocale());
- if(!petname)
- petname = cinfo->Name;
- return std::string(petname);
- }
-
- return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1));
-}
-
-uint32 ObjectMgr::GeneratePetNumber()
-{
- return ++m_hiPetNumber;
-}
-
-void ObjectMgr::LoadCorpses()
-{
- uint32 count = 0;
- // 0 1 2 3 4 5 6 7 8 10
- QueryResult *result = CharacterDatabase.Query("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u corpses", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 guid = fields[result->GetFieldCount()-1].GetUInt32();
-
- Corpse *corpse = new Corpse;
- if(!corpse->LoadFromDB(guid,fields))
- {
- delete corpse;
- continue;
- }
-
- ObjectAccessor::Instance().AddCorpse(corpse);
-
- ++count;
- }
- while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u corpses", count );
-}
-
-void ObjectMgr::LoadReputationOnKill()
-{
- uint32 count = 0;
-
- // 0 1 2
- QueryResult *result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2,"
- // 3 4 5 6 7 8 9
- "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
- "FROM creature_onkill_reputation");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 creature_id = fields[0].GetUInt32();
-
- ReputationOnKillEntry repOnKill;
- repOnKill.repfaction1 = fields[1].GetUInt32();
- repOnKill.repfaction2 = fields[2].GetUInt32();
- repOnKill.is_teamaward1 = fields[3].GetBool();
- repOnKill.reputation_max_cap1 = fields[4].GetUInt32();
- repOnKill.repvalue1 = fields[5].GetInt32();
- repOnKill.is_teamaward2 = fields[6].GetBool();
- repOnKill.reputation_max_cap2 = fields[7].GetUInt32();
- repOnKill.repvalue2 = fields[8].GetInt32();
- repOnKill.team_dependent = fields[9].GetUInt8();
-
- if(!GetCreatureTemplate(creature_id))
- {
- sLog.outErrorDb("Table `creature_onkill_reputation` have data for not existed creature entry (%u), skipped",creature_id);
- continue;
- }
-
- if(repOnKill.repfaction1)
- {
- FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(repOnKill.repfaction1);
- if(!factionEntry1)
- {
- sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction1);
- continue;
- }
- }
-
- if(repOnKill.repfaction2)
- {
- FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(repOnKill.repfaction2);
- if(!factionEntry2)
- {
- sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction2);
- continue;
- }
- }
-
- mRepOnKill[creature_id] = repOnKill;
-
- ++count;
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString(">> Loaded %u creature award reputation definitions", count);
-}
-
-void ObjectMgr::LoadWeatherZoneChances()
-{
- uint32 count = 0;
-
- // 0 1 2 3 4 5 6 7 8 9 10 11 12
- QueryResult *result = WorldDatabase.Query("SELECT zone, spring_rain_chance, spring_snow_chance, spring_storm_chance, summer_rain_chance, summer_snow_chance, summer_storm_chance, fall_rain_chance, fall_snow_chance, fall_storm_chance, winter_rain_chance, winter_snow_chance, winter_storm_chance FROM game_weather");
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded 0 weather definitions. DB table `game_weather` is empty.");
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 zone_id = fields[0].GetUInt32();
-
- WeatherZoneChances& wzc = mWeatherZoneMap[zone_id];
-
- for(int season = 0; season < WEATHER_SEASONS; ++season)
- {
- wzc.data[season].rainChance = fields[season * (MAX_WEATHER_TYPE-1) + 1].GetUInt32();
- wzc.data[season].snowChance = fields[season * (MAX_WEATHER_TYPE-1) + 2].GetUInt32();
- wzc.data[season].stormChance = fields[season * (MAX_WEATHER_TYPE-1) + 3].GetUInt32();
-
- if(wzc.data[season].rainChance > 100)
- {
- wzc.data[season].rainChance = 25;
- sLog.outErrorDb("Weather for zone %u season %u has wrong rain chance > 100%",zone_id,season);
- }
-
- if(wzc.data[season].snowChance > 100)
- {
- wzc.data[season].snowChance = 25;
- sLog.outErrorDb("Weather for zone %u season %u has wrong snow chance > 100%",zone_id,season);
- }
-
- if(wzc.data[season].stormChance > 100)
- {
- wzc.data[season].stormChance = 25;
- sLog.outErrorDb("Weather for zone %u season %u has wrong storm chance > 100%",zone_id,season);
- }
- }
-
- ++count;
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString(">> Loaded %u weather definitions", count);
-}
-
-void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t)
-{
- mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = t;
- WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance);
- if(t)
- WorldDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance);
-}
-
-void ObjectMgr::DeleteCreatureData(uint32 guid)
-{
- // remove mapid*cellid -> guid_set map
- CreatureData const* data = GetCreatureData(guid);
- if(data)
- RemoveCreatureFromGrid(guid, data);
-
- mCreatureDataMap.erase(guid);
-}
-
-void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t)
-{
- mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = t;
- WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance);
- if(t)
- WorldDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance);
-}
-
-void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance)
-{
- RespawnTimes::iterator next;
-
- for(RespawnTimes::iterator itr = mGORespawnTimes.begin(); itr != mGORespawnTimes.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if(GUID_HIPART(itr->first)==instance)
- mGORespawnTimes.erase(itr);
- }
-
- for(RespawnTimes::iterator itr = mCreatureRespawnTimes.begin(); itr != mCreatureRespawnTimes.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if(GUID_HIPART(itr->first)==instance)
- mCreatureRespawnTimes.erase(itr);
- }
-
- WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", instance);
- WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", instance);
-}
-
-void ObjectMgr::DeleteGOData(uint32 guid)
-{
- // remove mapid*cellid -> guid_set map
- GameObjectData const* data = GetGOData(guid);
- if(data)
- RemoveGameobjectFromGrid(guid, data);
-
- mGameObjectDataMap.erase(guid);
-}
-
-void ObjectMgr::AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance)
-{
- // corpses are always added to spawn mode 0 and they are spawned by their instance id
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(mapid,0)][cellid];
- cell_guids.corpses[player_guid] = instance;
-}
-
-void ObjectMgr::DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid)
-{
- // corpses are always added to spawn mode 0 and they are spawned by their instance id
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(mapid,0)][cellid];
- cell_guids.corpses.erase(player_guid);
-}
-
-void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map,char const* table)
-{
- map.clear(); // need for reload case
-
- uint32 count = 0;
-
- QueryResult *result = WorldDatabase.PQuery("SELECT id,quest FROM %s",table);
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded 0 quest relations from %s. DB table `%s` is empty.",table,table);
- return;
- }
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- uint32 id = fields[0].GetUInt32();
- uint32 quest = fields[1].GetUInt32();
-
- if(mQuestTemplates.find(quest) == mQuestTemplates.end())
- {
- sLog.outErrorDb("Table `%s: Quest %u listed for entry %u does not exist.",table,quest,id);
- continue;
- }
-
- map.insert(QuestRelations::value_type(id,quest));
-
- ++count;
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString(">> Loaded %u quest relations from %s", count,table);
-}
-
-void ObjectMgr::LoadGameobjectQuestRelations()
-{
- LoadQuestRelationsHelper(mGOQuestRelations,"gameobject_questrelation");
-
- for(QuestRelations::iterator itr = mGOQuestRelations.begin(); itr != mGOQuestRelations.end(); ++itr)
- {
- GameObjectInfo const* goInfo = GetGameObjectInfo(itr->first);
- if(!goInfo)
- sLog.outErrorDb("Table `gameobject_questrelation` have data for not existed gameobject entry (%u) and existed quest %u",itr->first,itr->second);
- else if(goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
- sLog.outErrorDb("Table `gameobject_questrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER",itr->first,itr->second);
- }
-}
-
-void ObjectMgr::LoadGameobjectInvolvedRelations()
-{
- LoadQuestRelationsHelper(mGOQuestInvolvedRelations,"gameobject_involvedrelation");
-
- for(QuestRelations::iterator itr = mGOQuestInvolvedRelations.begin(); itr != mGOQuestInvolvedRelations.end(); ++itr)
- {
- GameObjectInfo const* goInfo = GetGameObjectInfo(itr->first);
- if(!goInfo)
- sLog.outErrorDb("Table `gameobject_involvedrelation` have data for not existed gameobject entry (%u) and existed quest %u",itr->first,itr->second);
- else if(goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
- sLog.outErrorDb("Table `gameobject_involvedrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER",itr->first,itr->second);
- }
-}
-
-void ObjectMgr::LoadCreatureQuestRelations()
-{
- LoadQuestRelationsHelper(mCreatureQuestRelations,"creature_questrelation");
-
- for(QuestRelations::iterator itr = mCreatureQuestRelations.begin(); itr != mCreatureQuestRelations.end(); ++itr)
- {
- CreatureInfo const* cInfo = GetCreatureTemplate(itr->first);
- if(!cInfo)
- sLog.outErrorDb("Table `creature_questrelation` have data for not existed creature entry (%u) and existed quest %u",itr->first,itr->second);
- else if(!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
- sLog.outErrorDb("Table `creature_questrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER",itr->first,itr->second);
- }
-}
-
-void ObjectMgr::LoadCreatureInvolvedRelations()
-{
- LoadQuestRelationsHelper(mCreatureQuestInvolvedRelations,"creature_involvedrelation");
-
- for(QuestRelations::iterator itr = mCreatureQuestInvolvedRelations.begin(); itr != mCreatureQuestInvolvedRelations.end(); ++itr)
- {
- CreatureInfo const* cInfo = GetCreatureTemplate(itr->first);
- if(!cInfo)
- sLog.outErrorDb("Table `creature_involvedrelation` have data for not existed creature entry (%u) and existed quest %u",itr->first,itr->second);
- else if(!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
- sLog.outErrorDb("Table `creature_involvedrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER",itr->first,itr->second);
- }
-}
-
-void ObjectMgr::LoadReservedPlayersNames()
-{
- m_ReservedNames.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query("SELECT name FROM reserved_name");
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u reserved player names", count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- Field* fields;
- do
- {
- bar.step();
- fields = result->Fetch();
- std::string name= fields[0].GetCppString();
- if(normalizePlayerName(name))
- {
- m_ReservedNames.insert(name);
- ++count;
- }
- } while ( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u reserved player names", count );
-}
-
-enum LanguageType
-{
- LT_BASIC_LATIN = 0x0000,
- LT_EXTENDEN_LATIN = 0x0001,
- LT_CYRILLIC = 0x0002,
- LT_EAST_ASIA = 0x0004,
- LT_ANY = 0xFFFF
-};
-
-static LanguageType GetRealmLanguageType(bool create)
-{
- switch(sWorld.getConfig(CONFIG_REALM_ZONE))
- {
- case REALM_ZONE_UNKNOWN: // any language
- case REALM_ZONE_DEVELOPMENT:
- case REALM_ZONE_TEST_SERVER:
- case REALM_ZONE_QA_SERVER:
- return LT_ANY;
- case REALM_ZONE_UNITED_STATES: // extended-Latin
- case REALM_ZONE_OCEANIC:
- case REALM_ZONE_LATIN_AMERICA:
- case REALM_ZONE_ENGLISH:
- case REALM_ZONE_GERMAN:
- case REALM_ZONE_FRENCH:
- case REALM_ZONE_SPANISH:
- return LT_EXTENDEN_LATIN;
- case REALM_ZONE_KOREA: // East-Asian
- case REALM_ZONE_TAIWAN:
- case REALM_ZONE_CHINA:
- return LT_EAST_ASIA;
- case REALM_ZONE_RUSSIAN: // Cyrillic
- return LT_CYRILLIC;
- default:
- return create ? LT_BASIC_LATIN : LT_ANY; // basic-Latin at create, any at login
- }
-}
-
-bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create = false)
-{
- if(strictMask==0) // any language, ignore realm
- {
- if(isExtendedLatinString(wstr,numericOrSpace))
- return true;
- if(isCyrillicString(wstr,numericOrSpace))
- return true;
- if(isEastAsianString(wstr,numericOrSpace))
- return true;
- return false;
- }
-
- if(strictMask & 0x2) // realm zone specific
- {
- LanguageType lt = GetRealmLanguageType(create);
- if(lt & LT_EXTENDEN_LATIN)
- if(isExtendedLatinString(wstr,numericOrSpace))
- return true;
- if(lt & LT_CYRILLIC)
- if(isCyrillicString(wstr,numericOrSpace))
- return true;
- if(lt & LT_EAST_ASIA)
- if(isEastAsianString(wstr,numericOrSpace))
- return true;
- }
-
- if(strictMask & 0x1) // basic Latin
- {
- if(isBasicLatinString(wstr,numericOrSpace))
- return true;
- }
-
- return false;
-}
-
-bool ObjectMgr::IsValidName( std::string name, bool create )
-{
- std::wstring wname;
- if(!Utf8toWStr(name,wname))
- return false;
-
- if(wname.size() < 1 || wname.size() > MAX_PLAYER_NAME)
- return false;
-
- uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_PLAYER_NAMES);
-
- return isValidString(wname,strictMask,false,create);
-}
-
-bool ObjectMgr::IsValidCharterName( std::string name )
-{
- std::wstring wname;
- if(!Utf8toWStr(name,wname))
- return false;
-
- if(wname.size() < 1)
- return false;
-
- uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_CHARTER_NAMES);
-
- return isValidString(wname,strictMask,true);
-}
-
-bool ObjectMgr::IsValidPetName( std::string name )
-{
- std::wstring wname;
- if(!Utf8toWStr(name,wname))
- return false;
-
- if(wname.size() < 1)
- return false;
-
- uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_PET_NAMES);
-
- return isValidString(wname,strictMask,false);
-}
-
-int ObjectMgr::GetIndexForLocale( LocaleConstant loc )
-{
- if(loc==LOCALE_enUS)
- return -1;
-
- for(size_t i=0;i < m_LocalForIndex.size(); ++i)
- if(m_LocalForIndex[i]==loc)
- return i;
-
- return -1;
-}
-
-LocaleConstant ObjectMgr::GetLocaleForIndex(int i)
-{
- if (i<0 || i>=m_LocalForIndex.size())
- return LOCALE_enUS;
-
- return m_LocalForIndex[i];
-}
-
-int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc )
-{
- if(loc==LOCALE_enUS)
- return -1;
-
- for(size_t i=0;i < m_LocalForIndex.size(); ++i)
- if(m_LocalForIndex[i]==loc)
- return i;
-
- m_LocalForIndex.push_back(loc);
- return m_LocalForIndex.size()-1;
-}
-
-void ObjectMgr::LoadBattleMastersEntry()
-{
- mBattleMastersMap.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" );
-
- uint32 count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
- uint32 bgTypeId = fields[1].GetUInt32();
-
- mBattleMastersMap[entry] = bgTypeId;
-
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u battlemaster entries", count );
-}
-
-void ObjectMgr::LoadGameObjectForQuests()
-{
- mGameObjectForQuestSet.clear(); // need for reload case
-
- uint32 count = 0;
-
- // collect GO entries for GO that must activated
- for(uint32 go_entry = 1; go_entry < sGOStorage.MaxEntry; ++go_entry)
- {
- GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(go_entry);
- if(!goInfo)
- continue;
-
- switch(goInfo->type)
- {
- // scan GO chest with loot including quest items
- case GAMEOBJECT_TYPE_CHEST:
- {
- uint32 loot_id = GameObject::GetLootId(goInfo);
-
- // find quest loot for GO
- if(LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
- {
- mGameObjectForQuestSet.insert(go_entry);
- ++count;
- }
- break;
- }
- case GAMEOBJECT_TYPE_GOOBER:
- {
- if(goInfo->goober.questId) //quests objects
- {
- mGameObjectForQuestSet.insert(go_entry);
- count++;
- }
- break;
- }
- default:
- break;
- }
- }
-
- sLog.outString();
- sLog.outString( ">> Loaded %u GameObject for quests", count );
-}
-
-bool ObjectMgr::LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value)
-{
- // cleanup affected map part for reloading case
- for(TrinityStringLocaleMap::iterator itr = mTrinityStringLocaleMap.begin(); itr != mTrinityStringLocaleMap.end();)
- {
- if(itr->first >= min_value && itr->first <= max_value)
- {
- TrinityStringLocaleMap::iterator itr2 = itr;
- ++itr;
- mTrinityStringLocaleMap.erase(itr2);
- }
- else
- ++itr;
- }
-
- QueryResult *result = db.PQuery("SELECT entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8 FROM %s",table);
-
- if(!result)
- {
- barGoLink bar(1);
-
- bar.step();
-
- sLog.outString("");
- if(min_value > 0) // error only in case internal strings
- sLog.outErrorDb(">> Loaded 0 trinity strings. DB table `%s` is empty. Cannot continue.",table);
- else
- sLog.outString(">> Loaded 0 string templates. DB table `%s` is empty.",table);
- return false;
- }
-
- uint32 count = 0;
-
- barGoLink bar(result->GetRowCount());
-
- do
- {
- Field *fields = result->Fetch();
- bar.step();
-
- int32 entry = fields[0].GetInt32();
-
- if(entry==0)
- {
- sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.",table);
- continue;
- }
- else if(entry < min_value || entry > max_value)
- {
- int32 start = min_value > 0 ? min_value : max_value;
- int32 end = min_value > 0 ? max_value : min_value;
- sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,start,end);
- continue;
- }
-
- TrinityStringLocale& data = mTrinityStringLocaleMap[entry];
-
- if(data.Content.size() > 0)
- {
- sLog.outErrorDb("Table `%s` contain data for already loaded entry %i (from another table?), ignored.",table,entry);
- continue;
- }
-
- data.Content.resize(1);
- ++count;
-
- // 0 -> default, idx in to idx+1
- data.Content[0] = fields[1].GetCppString();
-
- for(int i = 1; i < MAX_LOCALE; ++i)
- {
- std::string str = fields[i+1].GetCppString();
- if(!str.empty())
- {
- int idx = GetOrNewIndexForLocale(LocaleConstant(i));
- if(idx >= 0)
- {
- // 0 -> default, idx in to idx+1
- if(data.Content.size() <= idx+1)
- data.Content.resize(idx+2);
-
- data.Content[idx+1] = str;
- }
- }
- }
- } while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- if(min_value > 0) // internal Trinity strings
- sLog.outString( ">> Loaded %u Trinity strings from table %s", count,table);
- else
- sLog.outString( ">> Loaded %u string templates from %s", count,table);
-
- return true;
-}
-
-const char *ObjectMgr::GetTrinityString(int32 entry, int locale_idx) const
-{
- // locale_idx==-1 -> default, locale_idx >= 0 in to idx+1
- // Content[0] always exist if exist TrinityStringLocale
- if(TrinityStringLocale const *msl = GetTrinityStringLocale(entry))
- {
- if(msl->Content.size() > locale_idx+1 && !msl->Content[locale_idx+1].empty())
- return msl->Content[locale_idx+1].c_str();
- else
- return msl->Content[0].c_str();
- }
-
- if(entry > 0)
- sLog.outErrorDb("Entry %i not found in `trinity_string` table.",entry);
- else
- sLog.outErrorDb("Trinity string entry %i not found in DB.",entry);
- return "<error>";
-}
-
-void ObjectMgr::LoadSpellDisabledEntrys()
-{
- m_DisabledPlayerSpells.clear(); // need for reload case
- m_DisabledCreatureSpells.clear();
- QueryResult *result = WorldDatabase.Query("SELECT entry, disable_mask FROM spell_disabled");
-
- uint32 total_count = 0;
-
- if( !result )
- {
- barGoLink bar( 1 );
- bar.step();
-
- sLog.outString();
- sLog.outString( ">> Loaded %u disabled spells", total_count );
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- Field* fields;
- do
- {
- bar.step();
- fields = result->Fetch();
- uint32 spellid = fields[0].GetUInt32();
- if(!sSpellStore.LookupEntry(spellid))
- {
- sLog.outErrorDb("Spell entry %u from `spell_disabled` doesn't exist in dbc, ignoring.",spellid);
- continue;
- }
- uint32 disable_mask = fields[1].GetUInt32();
- if(disable_mask & SPELL_DISABLE_PLAYER)
- m_DisabledPlayerSpells.insert(spellid);
- if(disable_mask & SPELL_DISABLE_CREATURE)
- m_DisabledCreatureSpells.insert(spellid);
- ++total_count;
- } while ( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u disabled spells from `spell_disabled`", total_count);
-}
-
-void ObjectMgr::LoadFishingBaseSkillLevel()
-{
- mFishingBaseForArea.clear(); // for reload case
-
- uint32 count = 0;
- QueryResult *result = WorldDatabase.Query("SELECT entry,skill FROM skill_fishing_base_level");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded `skill_fishing_base_level`, table is empty!");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
-
- Field *fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
- int32 skill = fields[1].GetInt32();
-
- AreaTableEntry const* fArea = GetAreaEntryByAreaID(entry);
- if(!fArea)
- {
- sLog.outErrorDb("AreaId %u defined in `skill_fishing_base_level` does not exist",entry);
- continue;
- }
-
- mFishingBaseForArea[entry] = skill;
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u areas for fishing base skill level", count );
-}
-
-// Searches for the same condition already in Conditions store
-// Returns Id if found, else adds it to Conditions and returns Id
-uint16 ObjectMgr::GetConditionId( ConditionType condition, uint32 value1, uint32 value2 )
-{
- PlayerCondition lc = PlayerCondition(condition, value1, value2);
- for (uint16 i=0; i < mConditions.size(); ++i)
- {
- if (lc == mConditions[i])
- return i;
- }
-
- mConditions.push_back(lc);
-
- if(mConditions.size() > 0xFFFF)
- {
- sLog.outError("Conditions store overflow! Current and later loaded conditions will ignored!");
- return 0;
- }
-
- return mConditions.size() - 1;
-}
-
-bool ObjectMgr::CheckDeclinedNames( std::wstring mainpart, DeclinedName const& names )
-{
- for(int i =0; i < MAX_DECLINED_NAME_CASES; ++i)
- {
- std::wstring wname;
- if(!Utf8toWStr(names.name[i],wname))
- return false;
-
- if(mainpart!=GetMainPartOfName(wname,i+1))
- return false;
- }
- return true;
-}
-
-const char* ObjectMgr::GetAreaTriggerScriptName(uint32 id)
-{
- AreaTriggerScriptMap::const_iterator i = mAreaTriggerScripts.find(id);
- if(i!= mAreaTriggerScripts.end())
- return i->second.c_str();
- return "";
-}
-
-// Checks if player meets the condition
-bool PlayerCondition::Meets(Player const * player) const
-{
- if( !player )
- return false; // player not present, return false
-
- switch (condition)
- {
- case CONDITION_NONE:
- return true; // empty condition, always met
- case CONDITION_AURA:
- return player->HasAura(value1, value2);
- case CONDITION_ITEM:
- return player->HasItemCount(value1, value2);
- case CONDITION_ITEM_EQUIPPED:
- return player->GetItemOrItemWithGemEquipped(value1) != NULL;
- case CONDITION_ZONEID:
- return player->GetZoneId() == value1;
- case CONDITION_REPUTATION_RANK:
- {
- FactionEntry const* faction = sFactionStore.LookupEntry(value1);
- return faction && player->GetReputationRank(faction) >= value2;
- }
- case CONDITION_TEAM:
- return player->GetTeam() == value1;
- case CONDITION_SKILL:
- return player->HasSkill(value1) && player->GetBaseSkillValue(value1) >= value2;
- case CONDITION_QUESTREWARDED:
- return player->GetQuestRewardStatus(value1);
- case CONDITION_QUESTTAKEN:
- {
- QuestStatus status = player->GetQuestStatus(value1);
- return (status == QUEST_STATUS_INCOMPLETE);
- }
- case CONDITION_AD_COMMISSION_AURA:
- {
- Unit::AuraMap const& auras = player->GetAuras();
- for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580)
- return true;
- return false;
- }
- case CONDITION_NO_AURA:
- return !player->HasAura(value1, value2);
- case CONDITION_ACTIVE_EVENT:
- return gameeventmgr.IsActiveEvent(value1);
- default:
- return false;
- }
-}
-
-// Verification of condition values validity
-bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 value2)
-{
- if( condition >= MAX_CONDITION) // Wrong condition type
- {
- sLog.outErrorDb("Condition has bad type of %u, skipped ", condition );
- return false;
- }
-
- switch (condition)
- {
- case CONDITION_AURA:
- {
- if(!sSpellStore.LookupEntry(value1))
- {
- sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1);
- return false;
- }
- if(value2 > 2)
- {
- sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2);
- return false;
- }
- break;
- }
- case CONDITION_ITEM:
- {
- ItemPrototype const *proto = objmgr.GetItemPrototype(value1);
- if(!proto)
- {
- sLog.outErrorDb("Item condition requires to have non existing item (%u), skipped", value1);
- return false;
- }
- break;
- }
- case CONDITION_ITEM_EQUIPPED:
- {
- ItemPrototype const *proto = objmgr.GetItemPrototype(value1);
- if(!proto)
- {
- sLog.outErrorDb("ItemEquipped condition requires to have non existing item (%u) equipped, skipped", value1);
- return false;
- }
- break;
- }
- case CONDITION_ZONEID:
- {
- AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(value1);
- if(!areaEntry)
- {
- sLog.outErrorDb("Zone condition requires to be in non existing area (%u), skipped", value1);
- return false;
- }
- if(areaEntry->zone != 0)
- {
- sLog.outErrorDb("Zone condition requires to be in area (%u) which is a subzone but zone expected, skipped", value1);
- return false;
- }
- break;
- }
- case CONDITION_REPUTATION_RANK:
- {
- FactionEntry const* factionEntry = sFactionStore.LookupEntry(value1);
- if(!factionEntry)
- {
- sLog.outErrorDb("Reputation condition requires to have reputation non existing faction (%u), skipped", value1);
- return false;
- }
- break;
- }
- case CONDITION_TEAM:
- {
- if (value1 != ALLIANCE && value1 != HORDE)
- {
- sLog.outErrorDb("Team condition specifies unknown team (%u), skipped", value1);
- return false;
- }
- break;
- }
- case CONDITION_SKILL:
- {
- SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(value1);
- if (!pSkill)
- {
- sLog.outErrorDb("Skill condition specifies non-existing skill (%u), skipped", value1);
- return false;
- }
- if (value2 < 1 || value2 > sWorld.GetConfigMaxSkillValue() )
- {
- sLog.outErrorDb("Skill condition specifies invalid skill value (%u), skipped", value2);
- return false;
- }
- break;
- }
- case CONDITION_QUESTREWARDED:
- case CONDITION_QUESTTAKEN:
- {
- Quest const *Quest = objmgr.GetQuestTemplate(value1);
- if (!Quest)
- {
- sLog.outErrorDb("Quest condition specifies non-existing quest (%u), skipped", value1);
- return false;
- }
- if(value2)
- sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2);
- break;
- }
- case CONDITION_AD_COMMISSION_AURA:
- {
- if(value1)
- sLog.outErrorDb("Quest condition has useless data in value1 (%u)!", value1);
- if(value2)
- sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2);
- break;
- }
- case CONDITION_NO_AURA:
- {
- if(!sSpellStore.LookupEntry(value1))
- {
- sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1);
- return false;
- }
- if(value2 > 2)
- {
- sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2);
- return false;
- }
- break;
- }
- case CONDITION_ACTIVE_EVENT:
- {
- GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
- if(value1 >=events.size() || !events[value1].isValid())
- {
- sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1);
- return false;
- }
- break;
- }
- }
- return true;
-}
-
-SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
-{
- switch(pSkill->categoryId)
- {
- case SKILL_CATEGORY_LANGUAGES: return SKILL_RANGE_LANGUAGE;
- case SKILL_CATEGORY_WEAPON:
- if(pSkill->id!=SKILL_FIST_WEAPONS)
- return SKILL_RANGE_LEVEL;
- else
- return SKILL_RANGE_MONO;
- case SKILL_CATEGORY_ARMOR:
- case SKILL_CATEGORY_CLASS:
- if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING)
- return SKILL_RANGE_MONO;
- else
- return SKILL_RANGE_LEVEL;
- case SKILL_CATEGORY_SECONDARY:
- case SKILL_CATEGORY_PROFESSION:
- // not set skills for professions and racial abilities
- if(IsProfessionSkill(pSkill->id))
- return SKILL_RANGE_RANK;
- else if(racial)
- return SKILL_RANGE_NONE;
- else
- return SKILL_RANGE_MONO;
- default:
- case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc
- case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND)
- return SKILL_RANGE_NONE;
- }
-}
-
-void ObjectMgr::LoadGameTele()
-{
- m_GameTeleMap.clear(); // for reload case
-
- uint32 count = 0;
- QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded `game_tele`, table is empty!");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 id = fields[0].GetUInt32();
-
- GameTele gt;
-
- gt.position_x = fields[1].GetFloat();
- gt.position_y = fields[2].GetFloat();
- gt.position_z = fields[3].GetFloat();
- gt.orientation = fields[4].GetFloat();
- gt.mapId = fields[5].GetUInt32();
- gt.name = fields[6].GetCppString();
-
- if(!MapManager::IsValidMapCoord(gt.mapId,gt.position_x,gt.position_y,gt.position_z,gt.orientation))
- {
- sLog.outErrorDb("Wrong position for id %u (name: %s) in `game_tele` table, ignoring.",id,gt.name.c_str());
- continue;
- }
-
- if(!Utf8toWStr(gt.name,gt.wnameLow))
- {
- sLog.outErrorDb("Wrong UTF8 name for id %u in `game_tele` table, ignoring.",id);
- continue;
- }
-
- wstrToLower( gt.wnameLow );
-
- m_GameTeleMap[id] = gt;
-
- ++count;
- }
- while (result->NextRow());
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u game tele's", count );
-}
-
-GameTele const* ObjectMgr::GetGameTele(std::string name) const
-{
- // explicit name case
- std::wstring wname;
- if(!Utf8toWStr(name,wname))
- return false;
-
- // converting string that we try to find to lower case
- wstrToLower( wname );
-
- // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
- const GameTele* alt = NULL;
- for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr)
- {
- if(itr->second.wnameLow == wname)
- return &itr->second;
- else if (alt == NULL && itr->second.wnameLow.find(wname) != std::wstring::npos)
- alt = &itr->second;
- }
-
- return alt;
-}
-
-bool ObjectMgr::AddGameTele(GameTele& tele)
-{
- // find max id
- uint32 new_id = 0;
- for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr)
- if(itr->first > new_id)
- new_id = itr->first;
-
- // use next
- ++new_id;
-
- if(!Utf8toWStr(tele.name,tele.wnameLow))
- return false;
-
- wstrToLower( tele.wnameLow );
-
- m_GameTeleMap[new_id] = tele;
-
- return WorldDatabase.PExecuteLog("INSERT INTO game_tele (id,position_x,position_y,position_z,orientation,map,name) VALUES (%u,%f,%f,%f,%f,%d,'%s')",
- new_id,tele.position_x,tele.position_y,tele.position_z,tele.orientation,tele.mapId,tele.name.c_str());
-}
-
-bool ObjectMgr::DeleteGameTele(std::string name)
-{
- // explicit name case
- std::wstring wname;
- if(!Utf8toWStr(name,wname))
- return false;
-
- // converting string that we try to find to lower case
- wstrToLower( wname );
-
- for(GameTeleMap::iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr)
- {
- if(itr->second.wnameLow == wname)
- {
- WorldDatabase.PExecuteLog("DELETE FROM game_tele WHERE name = '%s'",itr->second.name.c_str());
- m_GameTeleMap.erase(itr);
- return true;
- }
- }
-
- return false;
-}
-
-void ObjectMgr::LoadTrainerSpell()
-{
- // For reload case
- for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
- itr->second.Clear();
- m_mCacheTrainerSpellMap.clear();
-
- std::set<uint32> skip_trainers;
-
- QueryResult *result = WorldDatabase.Query("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded `npc_trainer`, table is empty!");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- uint32 count = 0;
- do
- {
- bar.step();
-
- Field* fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
- uint32 spell = fields[1].GetUInt32();
-
- CreatureInfo const* cInfo = GetCreatureTemplate(entry);
-
- if(!cInfo)
- {
- sLog.outErrorDb("Table `npc_trainer` have entry for not existed creature template (Entry: %u), ignore", entry);
- continue;
- }
-
- if(!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
- {
- if(skip_trainers.count(entry) == 0)
- {
- sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry);
- skip_trainers.insert(entry);
- }
- continue;
- }
-
- SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell);
- if(!spellinfo)
- {
- sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u ) has non existing spell %u, ignore", entry,spell);
- continue;
- }
-
- if(!SpellMgr::IsSpellValid(spellinfo))
- {
- sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u) has broken learning spell %u, ignore", entry, spell);
- continue;
- }
-
- TrainerSpell* pTrainerSpell = new TrainerSpell();
- pTrainerSpell->spell = spell;
- pTrainerSpell->spellcost = fields[2].GetUInt32();
- pTrainerSpell->reqskill = fields[3].GetUInt32();
- pTrainerSpell->reqskillvalue = fields[4].GetUInt32();
- pTrainerSpell->reqlevel = fields[5].GetUInt32();
-
- if(!pTrainerSpell->reqlevel)
- pTrainerSpell->reqlevel = spellinfo->spellLevel;
-
-
- TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];
-
- if(SpellMgr::IsProfessionSpell(spell))
- data.trainerType = 2;
-
- data.spellList.push_back(pTrainerSpell);
- ++count;
-
- } while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded Trainers %d", count );
-}
-
-void ObjectMgr::LoadVendors()
-{
- // For reload case
- for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
- itr->second.Clear();
- m_mCacheVendorItemMap.clear();
-
- std::set<uint32> skip_vendors;
-
- QueryResult *result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded `npc_vendor`, table is empty!");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- uint32 count = 0;
- do
- {
- bar.step();
- Field* fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
- uint32 item_id = fields[1].GetUInt32();
- uint32 maxcount = fields[2].GetUInt32();
- uint32 incrtime = fields[3].GetUInt32();
- uint32 ExtendedCost = fields[4].GetUInt32();
-
- if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors))
- continue;
-
- VendorItemData& vList = m_mCacheVendorItemMap[entry];
-
- vList.AddItem(item_id,maxcount,incrtime,ExtendedCost);
- ++count;
-
- } while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %d Vendors ", count );
-}
-
-void ObjectMgr::LoadNpcTextId()
-{
-
- m_mCacheNpcTextIdMap.clear();
-
- QueryResult* result = WorldDatabase.Query("SELECT npc_guid, textid FROM npc_gossip");
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded `npc_gossip`, table is empty!");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- uint32 count = 0;
- uint32 guid,textid;
- do
- {
- bar.step();
-
- Field* fields = result->Fetch();
-
- guid = fields[0].GetUInt32();
- textid = fields[1].GetUInt32();
-
- if (!GetCreatureData(guid))
- {
- sLog.outErrorDb("Table `npc_gossip` have not existed creature (GUID: %u) entry, ignore. ",guid);
- continue;
- }
- if (!GetGossipText(textid))
- {
- sLog.outErrorDb("Table `npc_gossip` for creature (GUID: %u) have wrong Textid (%u), ignore. ", guid, textid);
- continue;
- }
-
- m_mCacheNpcTextIdMap[guid] = textid ;
- ++count;
-
- } while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %d NpcTextId ", count );
-}
-
-void ObjectMgr::LoadNpcOptions()
-{
- m_mCacheNpcOptionList.clear(); // For reload case
-
- QueryResult *result = WorldDatabase.Query(
- // 0 1 2 3 4 5 6 7 8
- "SELECT id,gossip_id,npcflag,icon,action,box_money,coded,option_text,box_text "
- "FROM npc_option");
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outErrorDb(">> Loaded `npc_option`, table is empty!");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- uint32 count = 0;
-
- do
- {
- bar.step();
-
- Field* fields = result->Fetch();
-
- GossipOption go;
- go.Id = fields[0].GetUInt32();
- go.GossipId = fields[1].GetUInt32();
- go.NpcFlag = fields[2].GetUInt32();
- go.Icon = fields[3].GetUInt32();
- go.Action = fields[4].GetUInt32();
- go.BoxMoney = fields[5].GetUInt32();
- go.Coded = fields[6].GetUInt8()!=0;
- go.OptionText = fields[7].GetCppString();
- go.BoxText = fields[8].GetCppString();
-
- m_mCacheNpcOptionList.push_back(go);
-
- ++count;
-
- } while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %d npc_option entries", count );
-}
-
-void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost, bool savetodb)
-{
- VendorItemData& vList = m_mCacheVendorItemMap[entry];
- vList.AddItem(item,maxcount,incrtime,extendedcost);
-
- if(savetodb) WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost);
-}
-
-bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item, bool savetodb)
-{
- CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry);
- if(iter == m_mCacheVendorItemMap.end())
- return false;
-
- if(!iter->second.FindItem(item))
- return false;
-
- iter->second.RemoveItem(item);
- if(savetodb) WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item);
- return true;
-}
-
-bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set<uint32>* skip_vendors, uint32 ORnpcflag ) const
-{
- CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry);
- if(!cInfo)
- {
- if(pl)
- ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
- else
- sLog.outErrorDb("Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry);
- return false;
- }
-
- if(!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
- {
- if(!skip_vendors || skip_vendors->count(vendor_entry)==0)
- {
- if(pl)
- ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
- else
- sLog.outErrorDb("Table `(game_event_)npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry);
-
- if(skip_vendors)
- skip_vendors->insert(vendor_entry);
- }
- return false;
- }
-
- if(!GetItemPrototype(item_id))
- {
- if(pl)
- ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
- else
- sLog.outErrorDb("Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id);
- return false;
- }
-
- if(ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
- {
- if(pl)
- ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost);
- else
- sLog.outErrorDb("Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry);
- return false;
- }
-
- if(maxcount > 0 && incrtime == 0)
- {
- if(pl)
- ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount);
- else
- sLog.outErrorDb( "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry);
- return false;
- }
- else if(maxcount==0 && incrtime > 0)
- {
- if(pl)
- ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0");
- else
- sLog.outErrorDb( "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry);
- return false;
- }
-
- VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
- if(!vItems)
- return true; // later checks for non-empty lists
-
- if(vItems->FindItem(item_id))
- {
- if(pl)
- ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,item_id);
- else
- sLog.outErrorDb( "Table `(game_event_)npc_vendor` has duplicate items %u for vendor (Entry: %u), ignore", item_id, vendor_entry);
- return false;
- }
-
- if(vItems->GetItemCount() >= MAX_VENDOR_ITEMS)
- {
- if(pl)
- ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
- else
- sLog.outErrorDb( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", vItems->GetItemCount(), MAX_VENDOR_ITEMS, vendor_entry);
- return false;
- }
-
- return true;
-}
-
-// Functions for scripting access
-const char* GetAreaTriggerScriptNameById(uint32 id)
-{
- return objmgr.GetAreaTriggerScriptName(id);
-}
-
-bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value)
-{
- if(start_value >= 0 || start_value <= end_value) // start/end reversed for negative values
- {
- sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), use (%d - %d) instead.",table,start_value,end_value,-1,std::numeric_limits<int32>::min());
- start_value = -1;
- end_value = std::numeric_limits<int32>::min();
- }
-
- // for scripting localized strings allowed use _only_ negative entries
- return objmgr.LoadTrinityStrings(db,table,end_value,start_value);
-}
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Database/SQLStorage.h"
+#include "Database/SQLStorageImpl.h"
+
+#include "Log.h"
+#include "MapManager.h"
+#include "ObjectMgr.h"
+#include "SpellMgr.h"
+#include "UpdateMask.h"
+#include "World.h"
+#include "WorldSession.h"
+#include "Group.h"
+#include "Guild.h"
+#include "ArenaTeam.h"
+#include "Transports.h"
+#include "ProgressBar.h"
+#include "Policies/SingletonImp.h"
+#include "Language.h"
+#include "GameEvent.h"
+#include "Spell.h"
+#include "Chat.h"
+#include "AccountMgr.h"
+#include "InstanceSaveMgr.h"
+#include "SpellAuras.h"
+#include "Util.h"
+
+INSTANTIATE_SINGLETON_1(ObjectMgr);
+
+ScriptMapMap sQuestEndScripts;
+ScriptMapMap sQuestStartScripts;
+ScriptMapMap sSpellScripts;
+ScriptMapMap sGameObjectScripts;
+ScriptMapMap sEventScripts;
+
+bool normalizePlayerName(std::string& name)
+{
+ if(name.empty())
+ return false;
+
+ wchar_t wstr_buf[MAX_INTERNAL_PLAYER_NAME+1];
+ size_t wstr_len = MAX_INTERNAL_PLAYER_NAME;
+
+ if(!Utf8toWStr(name,&wstr_buf[0],wstr_len))
+ return false;
+
+ wstr_buf[0] = wcharToUpper(wstr_buf[0]);
+ for(size_t i = 1; i < wstr_len; ++i)
+ wstr_buf[i] = wcharToLower(wstr_buf[i]);
+
+ if(!WStrToUtf8(wstr_buf,wstr_len,name))
+ return false;
+
+ return true;
+}
+
+LanguageDesc lang_description[LANGUAGES_COUNT] =
+{
+ { LANG_ADDON, 0, 0 },
+ { LANG_UNIVERSAL, 0, 0 },
+ { LANG_ORCISH, 669, SKILL_LANG_ORCISH },
+ { LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN },
+ { LANG_TAURAHE, 670, SKILL_LANG_TAURAHE },
+ { LANG_DWARVISH, 672, SKILL_LANG_DWARVEN },
+ { LANG_COMMON, 668, SKILL_LANG_COMMON },
+ { LANG_DEMONIC, 815, SKILL_LANG_DEMON_TONGUE },
+ { LANG_TITAN, 816, SKILL_LANG_TITAN },
+ { LANG_THALASSIAN, 813, SKILL_LANG_THALASSIAN },
+ { LANG_DRACONIC, 814, SKILL_LANG_DRACONIC },
+ { LANG_KALIMAG, 817, SKILL_LANG_OLD_TONGUE },
+ { LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH },
+ { LANG_TROLL, 7341, SKILL_LANG_TROLL },
+ { LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK },
+ { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI },
+ { LANG_ZOMBIE, 0, 0 },
+ { LANG_GNOMISH_BINARY, 0, 0 },
+ { LANG_GOBLIN_BINARY, 0, 0 }
+};
+
+LanguageDesc const* GetLanguageDescByID(uint32 lang)
+{
+ for(int i = 0; i < LANGUAGES_COUNT; ++i)
+ {
+ if(uint32(lang_description[i].lang_id) == lang)
+ return &lang_description[i];
+ }
+
+ return NULL;
+}
+
+ObjectMgr::ObjectMgr()
+{
+ m_hiCharGuid = 1;
+ m_hiCreatureGuid = 1;
+ m_hiPetGuid = 1;
+ m_hiItemGuid = 1;
+ m_hiGoGuid = 1;
+ m_hiDoGuid = 1;
+ m_hiCorpseGuid = 1;
+ m_hiPetNumber = 1;
+ m_ItemTextId = 1;
+ m_mailid = 1;
+ m_auctionid = 1;
+ m_guildId = 1;
+ m_arenaTeamId = 1;
+
+ mGuildBankTabPrice.resize(GUILD_BANK_MAX_TABS);
+ mGuildBankTabPrice[0] = 100;
+ mGuildBankTabPrice[1] = 250;
+ mGuildBankTabPrice[2] = 500;
+ mGuildBankTabPrice[3] = 1000;
+ mGuildBankTabPrice[4] = 2500;
+ mGuildBankTabPrice[5] = 5000;
+
+ // Only zero condition left, others will be added while loading DB tables
+ mConditions.resize(1);
+}
+
+ObjectMgr::~ObjectMgr()
+{
+ for( QuestMap::iterator i = mQuestTemplates.begin( ); i != mQuestTemplates.end( ); ++ i )
+ {
+ delete i->second;
+ }
+ mQuestTemplates.clear( );
+
+ for( GossipTextMap::iterator i = mGossipText.begin( ); i != mGossipText.end( ); ++ i )
+ {
+ delete i->second;
+ }
+ mGossipText.clear( );
+
+ mAreaTriggers.clear();
+
+ for(PetLevelInfoMap::iterator i = petInfo.begin( ); i != petInfo.end( ); ++ i )
+ {
+ delete[] i->second;
+ }
+ petInfo.clear();
+
+ // free only if loaded
+ for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
+ delete[] playerClassInfo[class_].levelInfo;
+
+ for (int race = 0; race < MAX_RACES; ++race)
+ for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
+ delete[] playerInfo[race][class_].levelInfo;
+
+ // free group and guild objects
+ for (GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr)
+ delete (*itr);
+ for (GuildSet::iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
+ delete (*itr);
+
+ for (CachePlayerInfoMap::iterator itr = m_mPlayerInfoMap.begin(); itr != m_mPlayerInfoMap.end(); ++itr)
+ delete itr->second;
+
+ for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
+ delete itr->second;
+
+ for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
+ itr->second.Clear();
+
+ for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
+ itr->second.Clear();
+}
+
+void ObjectMgr::LoadPlayerInfoInCache()
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT guid, name, data, class FROM characters");
+ if(!result)
+ {
+ sLog.outError( "Loading Player Cache failed.");
+ return;
+ }
+
+ PCachePlayerInfo pPPlayerInfo = NULL;
+ Field *fields = NULL;
+ Tokens tdata;
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ bar.step();
+ fields = result->Fetch();
+ pPPlayerInfo = new CachePlayerInfo();
+
+ pPPlayerInfo->sPlayerName = fields[1].GetString();
+
+ tdata.clear();
+ tdata = StrSplit(fields[2].GetCppString(), " ");
+
+ pPPlayerInfo->unLevel = Player::GetUInt32ValueFromArray(tdata,UNIT_FIELD_LEVEL);
+ pPPlayerInfo->unfield = Player::GetUInt32ValueFromArray(tdata,UNIT_FIELD_BYTES_0);
+
+ pPPlayerInfo->unArenaInfoId0 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6);
+ pPPlayerInfo->unArenaInfoId1 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6);
+ pPPlayerInfo->unArenaInfoId2 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6);
+
+ pPPlayerInfo->unArenaInfoSlot0 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5);
+ pPPlayerInfo->unArenaInfoSlot1 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5);
+ pPPlayerInfo->unArenaInfoSlot2 = Player::GetUInt32ValueFromArray(tdata,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5);
+
+ pPPlayerInfo->unClass = (uint32)fields[3].GetUInt32();
+ m_mPlayerInfoMap[fields[0].GetUInt32()] = pPPlayerInfo;
+ }
+ while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded info about %d players", m_mPlayerInfoMap.size());
+}
+
+PCachePlayerInfo ObjectMgr::GetPlayerInfoFromCache(uint32 unPlayerGuid) const
+{
+ //Now m_mPlayerInfoMap is using only for search, but when dinamic inserting/removing
+ //will be implemented we should lock it to prevent simultaneous access.
+ //Inserting - when new created player is saving
+ //Removing - when player has been deleted
+ CachePlayerInfoMap::const_iterator ipos = m_mPlayerInfoMap.find(unPlayerGuid);
+ return ipos == m_mPlayerInfoMap.end() ? NULL : ipos->second;
+}
+
+Group * ObjectMgr::GetGroupByLeader(const uint64 &guid) const
+{
+ for(GroupSet::const_iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr)
+ if ((*itr)->GetLeaderGUID() == guid)
+ return *itr;
+
+ return NULL;
+}
+
+Guild * ObjectMgr::GetGuildById(const uint32 GuildId) const
+{
+ for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++)
+ if ((*itr)->GetId() == GuildId)
+ return *itr;
+
+ return NULL;
+}
+
+Guild * ObjectMgr::GetGuildByName(std::string guildname) const
+{
+ for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++)
+ if ((*itr)->GetName() == guildname)
+ return *itr;
+
+ return NULL;
+}
+
+std::string ObjectMgr::GetGuildNameById(const uint32 GuildId) const
+{
+ for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); itr++)
+ if ((*itr)->GetId() == GuildId)
+ return (*itr)->GetName();
+
+ return "";
+}
+
+Guild* ObjectMgr::GetGuildByLeader(const uint64 &guid) const
+{
+ for(GuildSet::const_iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
+ if( (*itr)->GetLeader() == guid)
+ return *itr;
+
+ return NULL;
+}
+
+ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const
+{
+ for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++)
+ if ((*itr)->GetId() == ArenaTeamId)
+ return *itr;
+
+ return NULL;
+}
+
+ArenaTeam* ObjectMgr::GetArenaTeamByName(std::string arenateamname) const
+{
+ for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++)
+ if ((*itr)->GetName() == arenateamname)
+ return *itr;
+
+ return NULL;
+}
+
+ArenaTeam* ObjectMgr::GetArenaTeamByCapitan(uint64 const& guid) const
+{
+ for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); itr++)
+ if ((*itr)->GetCaptain() == guid)
+ return *itr;
+
+ return NULL;
+}
+
+AuctionHouseObject * ObjectMgr::GetAuctionsMap( uint32 location )
+{
+ switch ( location )
+ {
+ case 6: //horde
+ return & mHordeAuctions;
+ break;
+ case 2: //alliance
+ return & mAllianceAuctions;
+ break;
+ default: //neutral
+ return & mNeutralAuctions;
+ }
+}
+
+uint32 ObjectMgr::GetAuctionCut(uint32 location, uint32 highBid)
+{
+ if (location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
+ return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
+ else
+ return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
+}
+
+uint32 ObjectMgr::GetAuctionDeposit(uint32 location, uint32 time, Item *pItem)
+{
+ float percentance; // in 0..1
+ if ( location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
+ percentance = 0.75f;
+ else
+ percentance = 0.15f;
+
+ percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT);
+
+ return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) );
+}
+
+/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
+uint32 ObjectMgr::GetAuctionOutBid(uint32 currentBid)
+{
+ uint32 outbid = (currentBid / 100) * 5;
+ if (!outbid)
+ outbid = 1;
+ return outbid;
+}
+
+//does not clear ram
+void ObjectMgr::SendAuctionWonMail( AuctionEntry *auction )
+{
+ Item *pItem = GetAItem(auction->item_guidlow);
+ if(!pItem)
+ return;
+
+ uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
+ Player *bidder = GetPlayer(bidder_guid);
+
+ uint32 bidder_accId = 0;
+
+ // data for gm.log
+ if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+ {
+ uint32 bidder_security = 0;
+ std::string bidder_name;
+ if (bidder)
+ {
+ bidder_accId = bidder->GetSession()->GetAccountId();
+ bidder_security = bidder->GetSession()->GetSecurity();
+ bidder_name = bidder->GetName();
+ }
+ else
+ {
+ bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
+ bidder_security = accmgr.GetSecurity(bidder_accId);
+
+ if(bidder_security > SEC_PLAYER ) // not do redundant DB requests
+ {
+ if(!GetPlayerNameByGUID(bidder_guid,bidder_name))
+ bidder_name = GetTrinityStringForDBCLocale(LANG_UNKNOWN);
+ }
+ }
+
+ if( bidder_security > SEC_PLAYER )
+ {
+ std::string owner_name;
+ if(!GetPlayerNameByGUID(auction->owner,owner_name))
+ owner_name = GetTrinityStringForDBCLocale(LANG_UNKNOWN);
+
+ uint32 owner_accid = GetPlayerAccountIdByGUID(auction->owner);
+
+ sLog.outCommand("GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
+ bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
+ }
+ }
+ else if(!bidder)
+ bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
+
+ // receiver exist
+ if(bidder || bidder_accId)
+ {
+ std::ostringstream msgAuctionWonSubject;
+ msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
+
+ std::ostringstream msgAuctionWonBody;
+ msgAuctionWonBody.width(16);
+ msgAuctionWonBody << std::right << std::hex << auction->owner;
+ msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
+ sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() );
+
+ //prepare mail data... :
+ uint32 itemTextId = CreateItemText( msgAuctionWonBody.str() );
+
+ // set owner to bidder (to prevent delete item with sender char deleting)
+ // owner in `data` will set at mail receive and item extracting
+ CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
+ CharacterDatabase.CommitTransaction();
+
+ MailItemsInfo mi;
+ mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
+
+ if (bidder)
+ bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template);
+ else
+ RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
+
+ // will delete item or place to receiver mail list
+ WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
+ }
+ // receiver not exist
+ else
+ {
+ CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow());
+ RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
+ delete pItem;
+ }
+}
+
+void ObjectMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
+{
+ uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
+ Player *owner = GetPlayer(owner_guid);
+
+ // owner exist (online or offline)
+ if(owner || GetPlayerAccountIdByGUID(owner_guid))
+ {
+ std::ostringstream msgAuctionSalePendingSubject;
+ msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
+
+ std::ostringstream msgAuctionSalePendingBody;
+ uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
+
+ time_t distrTime = time(NULL) + HOUR;
+
+ msgAuctionSalePendingBody.width(16);
+ msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
+ msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
+ msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
+ msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
+
+ sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
+
+ uint32 itemTextId = CreateItemText( msgAuctionSalePendingBody.str() );
+
+ WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
+ }
+}
+
+//call this method to send mail to auction owner, when auction is successful, it does not clear ram
+void ObjectMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
+{
+ uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
+ Player *owner = GetPlayer(owner_guid);
+
+ uint32 owner_accId = 0;
+ if(!owner)
+ owner_accId = GetPlayerAccountIdByGUID(owner_guid);
+
+ // owner exist
+ if(owner || owner_accId)
+ {
+ std::ostringstream msgAuctionSuccessfulSubject;
+ msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
+
+ std::ostringstream auctionSuccessfulBody;
+ uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
+
+ auctionSuccessfulBody.width(16);
+ auctionSuccessfulBody << std::right << std::hex << auction->bidder;
+ auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
+ auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
+
+ sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
+
+ uint32 itemTextId = CreateItemText( auctionSuccessfulBody.str() );
+
+ uint32 profit = auction->bid + auction->deposit - auctionCut;
+
+ if (owner)
+ {
+ //send auction owner notification, bidder must be current!
+ owner->GetSession()->SendAuctionOwnerNotification( auction );
+ }
+
+ WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR);
+ }
+}
+
+//does not clear ram
+void ObjectMgr::SendAuctionExpiredMail( AuctionEntry * auction )
+{ //return an item in auction to its owner by mail
+ Item *pItem = GetAItem(auction->item_guidlow);
+ if(!pItem)
+ {
+ sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow);
+ return;
+ }
+
+ uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
+ Player *owner = GetPlayer(owner_guid);
+
+ uint32 owner_accId = 0;
+ if(!owner)
+ owner_accId = GetPlayerAccountIdByGUID(owner_guid);
+
+ // owner exist
+ if(owner || owner_accId)
+ {
+ std::ostringstream subject;
+ subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
+
+ if ( owner )
+ owner->GetSession()->SendAuctionOwnerNotification( auction );
+ else
+ RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
+
+ MailItemsInfo mi;
+ mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
+
+ // will delete item or place to receiver mail list
+ WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
+ }
+ // owner not found
+ else
+ {
+ CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem->GetGUIDLow());
+ RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
+ delete pItem;
+ }
+}
+
+CreatureInfo const* ObjectMgr::GetCreatureTemplate(uint32 id)
+{
+ return sCreatureStorage.LookupEntry<CreatureInfo>(id);
+}
+
+void ObjectMgr::LoadCreatureLocales()
+{
+ mCreatureLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,subname_loc1,name_loc2,subname_loc2,name_loc3,subname_loc3,name_loc4,subname_loc4,name_loc5,subname_loc5,name_loc6,subname_loc6,name_loc7,subname_loc7,name_loc8,subname_loc8 FROM locales_creature");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 creature locale strings. DB table `locales_creature` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ CreatureLocale& data = mCreatureLocaleMap[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[1+2*(i-1)].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Name.size() <= idx)
+ data.Name.resize(idx+1);
+
+ data.Name[idx] = str;
+ }
+ }
+ str = fields[1+2*(i-1)+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.SubName.size() <= idx)
+ data.SubName.resize(idx+1);
+
+ data.SubName[idx] = str;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() );
+}
+
+void ObjectMgr::LoadNpcOptionLocales()
+{
+ mNpcOptionLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,"
+ "option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2,"
+ "option_text_loc3,box_text_loc3,option_text_loc4,box_text_loc4,"
+ "option_text_loc5,box_text_loc5,option_text_loc6,box_text_loc6,"
+ "option_text_loc7,box_text_loc7,option_text_loc8,box_text_loc8 "
+ "FROM locales_npc_option");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ NpcOptionLocale& data = mNpcOptionLocaleMap[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[1+2*(i-1)].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.OptionText.size() <= idx)
+ data.OptionText.resize(idx+1);
+
+ data.OptionText[idx] = str;
+ }
+ }
+ str = fields[1+2*(i-1)+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.BoxText.size() <= idx)
+ data.BoxText.resize(idx+1);
+
+ data.BoxText[idx] = str;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u npc_option locale strings", mNpcOptionLocaleMap.size() );
+}
+
+struct SQLCreatureLoader : public SQLStorageLoaderBase<SQLCreatureLoader>
+{
+ template<class D>
+ void convert_from_str(uint32 field_pos, char *src, D &dst)
+ {
+ dst = D(objmgr.GetScriptId(src));
+ }
+};
+
+void ObjectMgr::LoadCreatureTemplates()
+{
+ SQLCreatureLoader loader;
+ loader.Load(sCreatureStorage);
+
+ sLog.outString( ">> Loaded %u creature definitions", sCreatureStorage.RecordCount );
+ sLog.outString();
+
+ std::set<uint32> heroicEntries; // already loaded heroic value in creatures
+ std::set<uint32> hasHeroicEntries; // already loaded creatures with heroic entry values
+
+ // check data correctness
+ for(uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i)
+ {
+ CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i);
+ if(!cInfo)
+ continue;
+
+ if(cInfo->HeroicEntry)
+ {
+ CreatureInfo const* heroicInfo = GetCreatureTemplate(cInfo->HeroicEntry);
+ if(!heroicInfo)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u not exist.",cInfo->HeroicEntry,cInfo->HeroicEntry);
+ continue;
+ }
+
+ if(heroicEntries.find(i)!=heroicEntries.end())
+ {
+ sLog.outErrorDb("Creature (Entry: %u) listed as heroic but have value in `heroic_entry`.",i);
+ continue;
+ }
+
+ if(heroicEntries.find(cInfo->HeroicEntry)!=heroicEntries.end())
+ {
+ sLog.outErrorDb("Creature (Entry: %u) already listed as heroic for another entry.",cInfo->HeroicEntry);
+ continue;
+ }
+
+ if(hasHeroicEntries.find(cInfo->HeroicEntry)!=hasHeroicEntries.end())
+ {
+ sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u have heroic entry also.",i,cInfo->HeroicEntry,cInfo->HeroicEntry);
+ continue;
+ }
+
+ if(cInfo->npcflag != heroicInfo->npcflag)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `npcflag` in heroic mode.",i);
+ continue;
+ }
+
+ if(cInfo->classNum != heroicInfo->classNum)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `classNum` in heroic mode.",i);
+ continue;
+ }
+
+ if(cInfo->race != heroicInfo->race)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `race` in heroic mode.",i);
+ continue;
+ }
+
+ if(cInfo->trainer_type != heroicInfo->trainer_type)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `trainer_type` in heroic mode.",i);
+ continue;
+ }
+
+ if(cInfo->trainer_spell != heroicInfo->trainer_spell)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) listed in `creature_template_substitution` has different `trainer_spell` in heroic mode.",i);
+ continue;
+ }
+
+ hasHeroicEntries.insert(i);
+ heroicEntries.insert(cInfo->HeroicEntry);
+ }
+
+ FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_A);
+ if(!factionTemplate)
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_A template (%u)", cInfo->Entry, cInfo->faction_A);
+
+ factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_H);
+ if(!factionTemplate)
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
+
+ // check model ids, supplying and sending non-existent ids to the client might crash them
+ if(cInfo->Modelid1 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid1))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u), setting it to 0", cInfo->Entry, cInfo->Modelid1);
+ const_cast<CreatureInfo*>(cInfo)->Modelid1 = 0;
+ }
+ if(cInfo->Modelid2 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid2))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid2);
+ const_cast<CreatureInfo*>(cInfo)->Modelid2 = 0;
+ }
+ if(cInfo->Modelid3 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid3))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u), setting it to 0", cInfo->Entry, cInfo->Modelid3);
+ const_cast<CreatureInfo*>(cInfo)->Modelid3 = 0;
+ }
+ if(cInfo->Modelid4 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid4))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid4);
+ const_cast<CreatureInfo*>(cInfo)->Modelid4 = 0;
+ }
+
+ if(cInfo->dmgschool >= MAX_SPELL_SCHOOL)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`",cInfo->Entry,cInfo->dmgschool);
+ const_cast<CreatureInfo*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL;
+ }
+
+ if(cInfo->baseattacktime == 0)
+ const_cast<CreatureInfo*>(cInfo)->baseattacktime = BASE_ATTACK_TIME;
+
+ if(cInfo->rangeattacktime == 0)
+ const_cast<CreatureInfo*>(cInfo)->rangeattacktime = BASE_ATTACK_TIME;
+
+ if((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE)
+ sLog.outErrorDb("Creature (Entry: %u) has wrong trainer type %u",cInfo->Entry,cInfo->trainer_type);
+
+ if(cInfo->InhabitType <= 0 || cInfo->InhabitType > INHABIT_ANYWHERE)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly",cInfo->Entry,cInfo->InhabitType);
+ const_cast<CreatureInfo*>(cInfo)->InhabitType = INHABIT_ANYWHERE;
+ }
+
+ if(cInfo->PetSpellDataId)
+ {
+ CreatureSpellDataEntry const* spellDataId = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId);
+ if(!spellDataId)
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing PetSpellDataId (%u)", cInfo->Entry, cInfo->PetSpellDataId);
+ }
+
+ if(cInfo->MovementType >= MAX_DB_MOTION_TYPE)
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has wrong movement generator type (%u), ignore and set to IDLE.",cInfo->Entry,cInfo->MovementType);
+ const_cast<CreatureInfo*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
+ }
+
+ if(cInfo->equipmentId > 0) // 0 no equipment
+ {
+ if(!GetEquipmentInfo(cInfo->equipmentId))
+ {
+ sLog.outErrorDb("Table `creature_template` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", cInfo->Entry, cInfo->equipmentId);
+ const_cast<CreatureInfo*>(cInfo)->equipmentId = 0;
+ }
+ }
+
+ /// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
+ if(cInfo->scale <= 0.0f)
+ {
+ uint32 modelid = cInfo->GetFirstValidModelId();
+ CreatureDisplayInfoEntry const* ScaleEntry = sCreatureDisplayInfoStore.LookupEntry(modelid);
+ const_cast<CreatureInfo*>(cInfo)->scale = ScaleEntry ? ScaleEntry->scale : 1.0f;
+ }
+ }
+}
+
+void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr)
+{
+ // Now add the auras, format "spellid effectindex spellid effectindex..."
+ char *p,*s;
+ std::vector<int> val;
+ s=p=(char*)reinterpret_cast<char const*>(addon->auras);
+ if(p)
+ {
+ while (p[0]!=0)
+ {
+ ++p;
+ if (p[0]==' ')
+ {
+ val.push_back(atoi(s));
+ s=++p;
+ }
+ }
+ if (p!=s)
+ val.push_back(atoi(s));
+
+ // free char* loaded memory
+ delete[] (char*)reinterpret_cast<char const*>(addon->auras);
+
+ // wrong list
+ if (val.size()%2)
+ {
+ addon->auras = NULL;
+ sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`.",guidEntryStr,addon->guidOrEntry,table);
+ return;
+ }
+ }
+
+ // empty list
+ if(val.empty())
+ {
+ addon->auras = NULL;
+ return;
+ }
+
+ // replace by new structures array
+ const_cast<CreatureDataAddonAura*&>(addon->auras) = new CreatureDataAddonAura[val.size()/2+1];
+
+ int i=0;
+ for(int j=0;j<val.size()/2;++j)
+ {
+ CreatureDataAddonAura& cAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]);
+ cAura.spell_id = (uint32)val[2*j+0];
+ cAura.effect_idx = (uint32)val[2*j+1];
+ if ( cAura.effect_idx > 2 )
+ {
+ sLog.outErrorDb("Creature (%s: %u) has wrong effect %u for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table);
+ continue;
+ }
+ SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura.spell_id);
+ if (!AdditionalSpellInfo)
+ {
+ sLog.outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table);
+ continue;
+ }
+
+ if (!AdditionalSpellInfo->Effect[cAura.effect_idx] || !AdditionalSpellInfo->EffectApplyAuraName[cAura.effect_idx])
+ {
+ sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table);
+ continue;
+ }
+
+ ++i;
+ }
+
+ // fill terminator element (after last added)
+ CreatureDataAddonAura& endAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]);
+ endAura.spell_id = 0;
+ endAura.effect_idx = 0;
+}
+
+void ObjectMgr::LoadCreatureAddons()
+{
+ sCreatureInfoAddonStorage.Load();
+
+ sLog.outString( ">> Loaded %u creature template addons", sCreatureInfoAddonStorage.RecordCount );
+ sLog.outString();
+
+ // check data correctness and convert 'auras'
+ for(uint32 i = 1; i < sCreatureInfoAddonStorage.MaxEntry; ++i)
+ {
+ CreatureDataAddon const* addon = sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(i);
+ if(!addon)
+ continue;
+
+ ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), "creature_template_addon", "Entry");
+
+ if(!sCreatureStorage.LookupEntry<CreatureInfo>(addon->guidOrEntry))
+ sLog.outErrorDb("Creature (Entry: %u) does not exist but has a record in `creature_template_addon`",addon->guidOrEntry);
+ }
+
+ sCreatureDataAddonStorage.Load();
+
+ sLog.outString( ">> Loaded %u creature addons", sCreatureDataAddonStorage.RecordCount );
+ sLog.outString();
+
+ // check data correctness and convert 'auras'
+ for(uint32 i = 1; i < sCreatureDataAddonStorage.MaxEntry; ++i)
+ {
+ CreatureDataAddon const* addon = sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(i);
+ if(!addon)
+ continue;
+
+ ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), "creature_addon", "GUIDLow");
+
+ if(mCreatureDataMap.find(addon->guidOrEntry)==mCreatureDataMap.end())
+ sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`",addon->guidOrEntry);
+ }
+}
+
+EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry)
+{
+ return sEquipmentStorage.LookupEntry<EquipmentInfo>(entry);
+}
+
+void ObjectMgr::LoadEquipmentTemplates()
+{
+ sEquipmentStorage.Load();
+
+ sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );
+ sLog.outString();
+}
+
+CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
+{
+ return sCreatureModelStorage.LookupEntry<CreatureModelInfo>(modelid);
+}
+
+uint32 ObjectMgr::ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data)
+{
+ // Load creature model (display id)
+ uint32 display_id = 0;
+
+ if (!data || data->displayid == 0) // use defaults from the template
+ {
+ display_id = cinfo->GetRandomValidModelId();
+ } else display_id = data->displayid; // overwritten from creature data
+
+ return display_id;
+}
+
+CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(uint32 display_id)
+{
+ CreatureModelInfo const *minfo = GetCreatureModelInfo(display_id);
+ if(!minfo)
+ return NULL;
+
+ // If a model for another gender exists, 50% chance to use it
+ if(minfo->modelid_other_gender != 0 && urand(0,1) == 0)
+ {
+ CreatureModelInfo const *minfo_tmp = GetCreatureModelInfo(minfo->modelid_other_gender);
+ if(!minfo_tmp)
+ {
+ sLog.outErrorDb("Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", minfo->modelid, minfo->modelid_other_gender);
+ return minfo; // not fatal, just use the previous one
+ }
+ else
+ return minfo_tmp;
+ }
+ else
+ return minfo;
+}
+
+void ObjectMgr::LoadCreatureModelInfo()
+{
+ sCreatureModelStorage.Load();
+
+ sLog.outString( ">> Loaded %u creature model based info", sCreatureModelStorage.RecordCount );
+ sLog.outString();
+
+ // check if combat_reach is valid
+ for(uint32 i = 1; i < sCreatureModelStorage.MaxEntry; ++i)
+ {
+ CreatureModelInfo const* mInfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(i);
+ if(!mInfo)
+ continue;
+
+ if(mInfo->combat_reach < 0.5f)
+ {
+ //sLog.outErrorDb("Creature model (Entry: %u) has invalid combat reach (%f), setting it to 0.5", mInfo->modelid, mInfo->combat_reach);
+ const_cast<CreatureModelInfo*>(mInfo)->combat_reach = 0.5f;
+ }
+ }
+}
+
+void ObjectMgr::LoadCreatures()
+{
+ uint32 count = 0;
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid,"
+ // 4 5 6 7 8 9 10 11
+ "equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint,"
+ // 12 13 14 15 16 17
+ "curhealth, curmana, DeathState, MovementType, spawnMask, event "
+ "FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outErrorDb(">> Loaded 0 creature. DB table `creature` is empty.");
+ return;
+ }
+
+ // build single time for check creature data
+ std::set<uint32> heroicCreatures;
+ for(uint32 i = 0; i < sCreatureStorage.MaxEntry; ++i)
+ if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
+ if(cInfo->HeroicEntry)
+ heroicCreatures.insert(cInfo->HeroicEntry);
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 guid = fields[0].GetUInt32();
+
+ CreatureData& data = mCreatureDataMap[guid];
+
+ data.id = fields[ 1].GetUInt32();
+ data.mapid = fields[ 2].GetUInt32();
+ data.displayid = fields[ 3].GetUInt32();
+ data.equipmentId = fields[ 4].GetUInt32();
+ data.posX = fields[ 5].GetFloat();
+ data.posY = fields[ 6].GetFloat();
+ data.posZ = fields[ 7].GetFloat();
+ data.orientation = fields[ 8].GetFloat();
+ data.spawntimesecs = fields[ 9].GetUInt32();
+ data.spawndist = fields[10].GetFloat();
+ data.currentwaypoint= fields[11].GetUInt32();
+ data.curhealth = fields[12].GetUInt32();
+ data.curmana = fields[13].GetUInt32();
+ data.is_dead = fields[14].GetBool();
+ data.movementType = fields[15].GetUInt8();
+ data.spawnMask = fields[16].GetUInt8();
+ int16 gameEvent = fields[17].GetInt16();
+
+ CreatureInfo const* cInfo = GetCreatureTemplate(data.id);
+ if(!cInfo)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u) with not existed creature entry %u, skipped.",guid,data.id );
+ continue;
+ }
+
+ if(heroicCreatures.find(data.id)!=heroicCreatures.end())
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u) that listed as heroic template in `creature_template_substitution`, skipped.",guid,data.id );
+ continue;
+ }
+
+ if(data.equipmentId > 0) // -1 no equipment, 0 use default
+ {
+ if(!GetEquipmentInfo(data.equipmentId))
+ {
+ sLog.outErrorDb("Table `creature` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", data.id, data.equipmentId);
+ data.equipmentId = -1;
+ }
+ }
+
+ if(cInfo->RegenHealth && data.curhealth < cInfo->minhealth)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`RegenHealth`=1 and low current health (%u), `creature_template`.`minhealth`=%u.",guid,data.id,data.curhealth, cInfo->minhealth );
+ data.curhealth = cInfo->minhealth;
+ }
+
+ if(data.curmana < cInfo->minmana)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with low current mana (%u), `creature_template`.`minmana`=%u.",guid,data.id,data.curmana, cInfo->minmana );
+ data.curmana = cInfo->minmana;
+ }
+
+ if(data.spawndist < 0.0f)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `spawndist`< 0, set to 0.",guid,data.id );
+ data.spawndist = 0.0f;
+ }
+ else if(data.movementType == RANDOM_MOTION_TYPE)
+ {
+ if(data.spawndist == 0.0f)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=1 (random movement) but with `spawndist`=0, replace by idle movement type (0).",guid,data.id );
+ data.movementType = IDLE_MOTION_TYPE;
+ }
+ }
+ else if(data.movementType == IDLE_MOTION_TYPE)
+ {
+ if(data.spawndist != 0.0f)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=0 (idle) have `spawndist`<>0, set to 0.",guid,data.id );
+ data.spawndist = 0.0f;
+ }
+ }
+
+ if (gameEvent==0) // if not this is to be managed by GameEvent System
+ AddCreatureToGrid(guid, &data);
+ ++count;
+
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u creatures", mCreatureDataMap.size() );
+}
+
+void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
+{
+ uint8 mask = data->spawnMask;
+ for(uint8 i = 0; mask != 0; i++, mask >>= 1)
+ {
+ if(mask & 1)
+ {
+ CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
+ uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
+
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
+ cell_guids.creatures.insert(guid);
+ }
+ }
+}
+
+void ObjectMgr::RemoveCreatureFromGrid(uint32 guid, CreatureData const* data)
+{
+ uint8 mask = data->spawnMask;
+ for(uint8 i = 0; mask != 0; i++, mask >>= 1)
+ {
+ if(mask & 1)
+ {
+ CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
+ uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
+
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
+ cell_guids.creatures.erase(guid);
+ }
+ }
+}
+
+void ObjectMgr::LoadGameobjects()
+{
+ uint32 count = 0;
+
+ // 0 1 2 3 4 5 6
+ QueryResult *result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation,"
+ // 7 8 9 10 11 12 13 14 15
+ "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, event "
+ "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 gameobjects. DB table `gameobject` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 guid = fields[0].GetUInt32();
+
+ GameObjectData& data = mGameObjectDataMap[guid];
+
+ data.id = fields[ 1].GetUInt32();
+ data.mapid = fields[ 2].GetUInt32();
+ data.posX = fields[ 3].GetFloat();
+ data.posY = fields[ 4].GetFloat();
+ data.posZ = fields[ 5].GetFloat();
+ data.orientation = fields[ 6].GetFloat();
+ data.rotation0 = fields[ 7].GetFloat();
+ data.rotation1 = fields[ 8].GetFloat();
+ data.rotation2 = fields[ 9].GetFloat();
+ data.rotation3 = fields[10].GetFloat();
+ data.spawntimesecs = fields[11].GetInt32();
+ data.animprogress = fields[12].GetUInt32();
+ data.go_state = fields[13].GetUInt32();
+ data.ArtKit = 0;
+ data.spawnMask = fields[14].GetUInt8();
+ int16 gameEvent = fields[15].GetInt16();
+
+ GameObjectInfo const* gInfo = GetGameObjectInfo(data.id);
+ if(!gInfo)
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u) with not existed gameobject entry %u, skipped.",guid,data.id );
+ continue;
+ }
+
+ if (gameEvent==0) // if not this is to be managed by GameEvent System
+ AddGameobjectToGrid(guid, &data);
+ ++count;
+
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u gameobjects", mGameObjectDataMap.size());
+}
+
+void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
+{
+ uint8 mask = data->spawnMask;
+ for(uint8 i = 0; mask != 0; i++, mask >>= 1)
+ {
+ if(mask & 1)
+ {
+ CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
+ uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
+
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
+ cell_guids.gameobjects.insert(guid);
+ }
+ }
+}
+
+void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data)
+{
+ uint8 mask = data->spawnMask;
+ for(uint8 i = 0; mask != 0; i++, mask >>= 1)
+ {
+ if(mask & 1)
+ {
+ CellPair cell_pair = Trinity::ComputeCellPair(data->posX, data->posY);
+ uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
+
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid,i)][cell_id];
+ cell_guids.gameobjects.erase(guid);
+ }
+ }
+}
+
+void ObjectMgr::LoadCreatureRespawnTimes()
+{
+ // remove outdated data
+ WorldDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
+
+ uint32 count = 0;
+
+ QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM creature_respawn");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded 0 creature respawn time.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 loguid = fields[0].GetUInt32();
+ uint64 respawn_time = fields[1].GetUInt64();
+ uint32 instance = fields[2].GetUInt32();
+
+ mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time);
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString( ">> Loaded %u creature respawn times", mCreatureRespawnTimes.size() );
+ sLog.outString();
+}
+
+void ObjectMgr::LoadGameobjectRespawnTimes()
+{
+ // remove outdated data
+ WorldDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
+
+ uint32 count = 0;
+
+ QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM gameobject_respawn");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString(">> Loaded 0 gameobject respawn time.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 loguid = fields[0].GetUInt32();
+ uint64 respawn_time = fields[1].GetUInt64();
+ uint32 instance = fields[2].GetUInt32();
+
+ mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time);
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString( ">> Loaded %u gameobject respawn times", mGORespawnTimes.size() );
+ sLog.outString();
+}
+
+// name must be checked to correctness (if received) before call this function
+uint64 ObjectMgr::GetPlayerGUIDByName(std::string name) const
+{
+ uint64 guid = 0;
+
+ CharacterDatabase.escape_string(name);
+
+ // Player name safe to sending to DB (checked at login) and this function using
+ QueryResult *result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE name = '%s'", name.c_str());
+ if(result)
+ {
+ guid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+
+ delete result;
+ }
+
+ return guid;
+}
+
+bool ObjectMgr::GetPlayerNameByGUID(const uint64 &guid, std::string &name) const
+{
+ // prevent DB access for online player
+ if(Player* player = GetPlayer(guid))
+ {
+ name = player->GetName();
+ return true;
+ }
+
+ PCachePlayerInfo pInfo = GetPlayerInfoFromCache(GUID_LOPART(guid));
+ if(pInfo)
+ {
+ name = pInfo->sPlayerName.c_str();
+ return true;
+ }
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
+
+ if(result)
+ {
+ name = (*result)[0].GetCppString();
+ delete result;
+ return true;
+ }
+
+ return false;
+}
+
+uint32 ObjectMgr::GetPlayerTeamByGUID(const uint64 &guid) const
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT race FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
+
+ if(result)
+ {
+ uint8 race = (*result)[0].GetUInt8();
+ delete result;
+ return Player::TeamForRace(race);
+ }
+
+ return 0;
+}
+
+uint32 ObjectMgr::GetPlayerAccountIdByGUID(const uint64 &guid) const
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
+ if(result)
+ {
+ uint32 acc = (*result)[0].GetUInt32();
+ delete result;
+ return acc;
+ }
+
+ return 0;
+}
+
+uint32 ObjectMgr::GetPlayerAccountIdByPlayerName(std::string name) const
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", name.c_str());
+ if(result)
+ {
+ uint32 acc = (*result)[0].GetUInt32();
+ delete result;
+ return acc;
+ }
+
+ return 0;
+}
+
+void ObjectMgr::LoadAuctions()
+{
+ QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
+ if( !result )
+ return;
+
+ Field *fields = result->Fetch();
+ uint32 AuctionCount=fields[0].GetUInt32();
+ delete result;
+
+ if(!AuctionCount)
+ return;
+
+ result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" );
+ if( !result )
+ return;
+
+ barGoLink bar( AuctionCount );
+
+ AuctionEntry *aItem;
+
+ do
+ {
+ fields = result->Fetch();
+
+ bar.step();
+
+ aItem = new AuctionEntry;
+ aItem->Id = fields[0].GetUInt32();
+ aItem->auctioneer = fields[1].GetUInt32();
+ aItem->item_guidlow = fields[2].GetUInt32();
+ aItem->item_template = fields[3].GetUInt32();
+ aItem->owner = fields[4].GetUInt32();
+ aItem->buyout = fields[5].GetUInt32();
+ aItem->time = fields[6].GetUInt32();
+ aItem->bidder = fields[7].GetUInt32();
+ aItem->bid = fields[8].GetUInt32();
+ aItem->startbid = fields[9].GetUInt32();
+ aItem->deposit = fields[10].GetUInt32();
+ aItem->location = fields[11].GetUInt8();
+ //check if sold item exists
+ if ( GetAItem( aItem->item_guidlow ) )
+ {
+ GetAuctionsMap( aItem->location )->AddAuction(aItem);
+ }
+ else
+ {
+ CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
+ sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
+ delete aItem;
+ }
+ } while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u auctions", AuctionCount );
+ sLog.outString();
+}
+
+void ObjectMgr::LoadItemLocales()
+{
+ mItemLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,description_loc1,name_loc2,description_loc2,name_loc3,description_loc3,name_loc4,description_loc4,name_loc5,description_loc5,name_loc6,description_loc6,name_loc7,description_loc7,name_loc8,description_loc8 FROM locales_item");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 Item locale strings. DB table `locales_item` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ ItemLocale& data = mItemLocaleMap[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[1+2*(i-1)].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Name.size() <= idx)
+ data.Name.resize(idx+1);
+
+ data.Name[idx] = str;
+ }
+ }
+
+ str = fields[1+2*(i-1)+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Description.size() <= idx)
+ data.Description.resize(idx+1);
+
+ data.Description[idx] = str;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u Item locale strings", mItemLocaleMap.size() );
+}
+
+struct SQLItemLoader : public SQLStorageLoaderBase<SQLItemLoader>
+{
+ template<class D>
+ void convert_from_str(uint32 field_pos, char *src, D &dst)
+ {
+ dst = D(objmgr.GetScriptId(src));
+ }
+};
+
+void ObjectMgr::LoadItemPrototypes()
+{
+ SQLItemLoader loader;
+ loader.Load(sItemStorage);
+ sLog.outString( ">> Loaded %u item prototypes", sItemStorage.RecordCount );
+ sLog.outString();
+
+ // check data correctness
+ for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i)
+ {
+ ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype >(i);
+ ItemEntry const *dbcitem = sItemStore.LookupEntry(i);
+ if(!proto)
+ {
+ /* to many errors, and possible not all items really used in game
+ if (dbcitem)
+ sLog.outErrorDb("Item (Entry: %u) doesn't exists in DB, but must exist.",i);
+ */
+ continue;
+ }
+
+ if(dbcitem)
+ {
+ if(proto->InventoryType != dbcitem->InventoryType)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).",i,proto->InventoryType,dbcitem->InventoryType);
+ // It safe let use InventoryType from DB
+ }
+
+ if(proto->DisplayInfoID != dbcitem->DisplayId)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %u display id, must be %u (using it).",i,proto->DisplayInfoID,dbcitem->DisplayId);
+ const_cast<ItemPrototype*>(proto)->DisplayInfoID = dbcitem->DisplayId;
+ }
+ if(proto->Sheath != dbcitem->Sheath)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %u sheath, must be %u (using it).",i,proto->Sheath,dbcitem->Sheath);
+ const_cast<ItemPrototype*>(proto)->Sheath = dbcitem->Sheath;
+ }
+ }
+ else
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct (not listed in list of existed items).",i);
+ }
+
+ if(proto->Class >= MAX_ITEM_CLASS)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class);
+ const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_JUNK;
+ }
+
+ if(proto->SubClass >= MaxItemSubclassValues[proto->Class])
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong Subclass value (%u) for class %u",i,proto->SubClass,proto->Class);
+ const_cast<ItemPrototype*>(proto)->SubClass = 0;// exist for all item classes
+ }
+
+ if(proto->Quality >= MAX_ITEM_QUALITY)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong Quality value (%u)",i,proto->Quality);
+ const_cast<ItemPrototype*>(proto)->Quality = ITEM_QUALITY_NORMAL;
+ }
+
+ if(proto->BuyCount <= 0)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong BuyCount value (%u), set to default(1).",i,proto->BuyCount);
+ const_cast<ItemPrototype*>(proto)->BuyCount = 1;
+ }
+
+ if(proto->InventoryType >= MAX_INVTYPE)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong InventoryType value (%u)",i,proto->InventoryType);
+ const_cast<ItemPrototype*>(proto)->InventoryType = INVTYPE_NON_EQUIP;
+ }
+
+ if(proto->RequiredSkill >= MAX_SKILL_TYPE)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong RequiredSkill value (%u)",i,proto->RequiredSkill);
+ const_cast<ItemPrototype*>(proto)->RequiredSkill = 0;
+ }
+
+ if(!(proto->AllowableClass & CLASSMASK_ALL_PLAYABLE))
+ {
+ sLog.outErrorDb("Item (Entry: %u) not have in `AllowableClass` any playable classes (%u) and can't be equipped.",i,proto->AllowableClass);
+ }
+
+ if(!(proto->AllowableRace & RACEMASK_ALL_PLAYABLE))
+ {
+ sLog.outErrorDb("Item (Entry: %u) not have in `AllowableRace` any playable races (%u) and can't be equipped.",i,proto->AllowableRace);
+ }
+
+ if(proto->RequiredSpell && !sSpellStore.LookupEntry(proto->RequiredSpell))
+ {
+ sLog.outErrorDb("Item (Entry: %u) have wrong (non-existed) spell in RequiredSpell (%u)",i,proto->RequiredSpell);
+ const_cast<ItemPrototype*>(proto)->RequiredSpell = 0;
+ }
+
+ if(proto->RequiredReputationRank >= MAX_REPUTATION_RANK)
+ sLog.outErrorDb("Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used.",i,proto->RequiredReputationRank);
+
+ if(proto->RequiredReputationFaction)
+ {
+ if(!sFactionStore.LookupEntry(proto->RequiredReputationFaction))
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)",i,proto->RequiredReputationFaction);
+ const_cast<ItemPrototype*>(proto)->RequiredReputationFaction = 0;
+ }
+
+ if(proto->RequiredReputationRank == MIN_REPUTATION_RANK)
+ sLog.outErrorDb("Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.",i);
+ }
+ else if(proto->RequiredReputationRank > MIN_REPUTATION_RANK)
+ sLog.outErrorDb("Item (Entry: %u) has RequiredReputationFaction ==0 but RequiredReputationRank > 0, rank setting is useless.",i);
+
+ if(proto->Stackable==0)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%u), replace by default 1.",i,proto->Stackable);
+ const_cast<ItemPrototype*>(proto)->Stackable = 1;
+ }
+ else if(proto->Stackable > 255)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has too large value in stackable (%u), replace by hardcoded upper limit (255).",i,proto->Stackable);
+ const_cast<ItemPrototype*>(proto)->Stackable = 255;
+ }
+
+ for (int j = 0; j < 10; j++)
+ {
+ // for ItemStatValue != 0
+ if(proto->ItemStat[j].ItemStatValue && proto->ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong stat_type%d (%u)",i,j+1,proto->ItemStat[j].ItemStatType);
+ const_cast<ItemPrototype*>(proto)->ItemStat[j].ItemStatType = 0;
+ }
+ }
+
+ for (int j = 0; j < 5; j++)
+ {
+ if(proto->Damage[j].DamageType >= MAX_SPELL_SCHOOL)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong dmg_type%d (%u)",i,j+1,proto->Damage[j].DamageType);
+ const_cast<ItemPrototype*>(proto)->Damage[j].DamageType = 0;
+ }
+ }
+
+ // special format
+ if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN)
+ {
+ // spell_1
+ if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format",i,0+1,proto->Spells[0].SpellTrigger);
+ const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+
+ // spell_2 have learning spell
+ if(proto->Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.",i,1+1,proto->Spells[1].SpellTrigger);
+ const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+ else if(!proto->Spells[1].SpellId)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not has expected spell in spellid_%d in special learning format.",i,1+1);
+ const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+ else
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[1].SpellId);
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);
+ const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+ // allowed only in special format
+ else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);
+ const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+ }
+
+ // spell_3*,spell_4*,spell_5* is empty
+ for (int j = 2; j < 5; j++)
+ {
+ if(proto->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger);
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+ else if(proto->Spells[j].SpellId != 0)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong spell in spellid_%d (%u) for learning special format",i,j+1,proto->Spells[j].SpellId);
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
+ }
+ }
+ }
+ // normal spell list
+ else
+ {
+ for (int j = 0; j < 5; j++)
+ {
+ if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger);
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
+ }
+
+ if(proto->Spells[j].SpellId)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[j].SpellId);
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
+ }
+ // allowed only in special format
+ else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);
+ const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
+ }
+ }
+ }
+ }
+
+ if(proto->Bonding >= MAX_BIND_TYPE)
+ sLog.outErrorDb("Item (Entry: %u) has wrong Bonding value (%u)",i,proto->Bonding);
+
+ if(proto->PageText && !sPageTextStore.LookupEntry<PageText>(proto->PageText))
+ sLog.outErrorDb("Item (Entry: %u) has non existing first page (Id:%u)", i,proto->PageText);
+
+ if(proto->LockID && !sLockStore.LookupEntry(proto->LockID))
+ sLog.outErrorDb("Item (Entry: %u) has wrong LockID (%u)",i,proto->LockID);
+
+ if(proto->Sheath >= MAX_SHEATHETYPE)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong Sheath (%u)",i,proto->Sheath);
+ const_cast<ItemPrototype*>(proto)->Sheath = SHEATHETYPE_NONE;
+ }
+
+ if(proto->RandomProperty && !sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(proto->RandomProperty)))
+ {
+ sLog.outErrorDb("Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)",i,proto->RandomProperty);
+ const_cast<ItemPrototype*>(proto)->RandomProperty = 0;
+ }
+
+ if(proto->RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(proto->RandomSuffix)))
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong RandomSuffix (%u)",i,proto->RandomSuffix);
+ const_cast<ItemPrototype*>(proto)->RandomSuffix = 0;
+ }
+
+ if(proto->ItemSet && !sItemSetStore.LookupEntry(proto->ItemSet))
+ {
+ sLog.outErrorDb("Item (Entry: %u) have wrong ItemSet (%u)",i,proto->ItemSet);
+ const_cast<ItemPrototype*>(proto)->ItemSet = 0;
+ }
+
+ if(proto->Area && !GetAreaEntryByAreaID(proto->Area))
+ sLog.outErrorDb("Item (Entry: %u) has wrong Area (%u)",i,proto->Area);
+
+ if(proto->Map && !sMapStore.LookupEntry(proto->Map))
+ sLog.outErrorDb("Item (Entry: %u) has wrong Map (%u)",i,proto->Map);
+
+ if(proto->TotemCategory && !sTotemCategoryStore.LookupEntry(proto->TotemCategory))
+ sLog.outErrorDb("Item (Entry: %u) has wrong TotemCategory (%u)",i,proto->TotemCategory);
+
+ for (int j = 0; j < 3; j++)
+ {
+ if(proto->Socket[j].Color && (proto->Socket[j].Color & SOCKET_COLOR_ALL) != proto->Socket[j].Color)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong socketColor_%d (%u)",i,j+1,proto->Socket[j].Color);
+ const_cast<ItemPrototype*>(proto)->Socket[j].Color = 0;
+ }
+ }
+
+ if(proto->GemProperties && !sGemPropertiesStore.LookupEntry(proto->GemProperties))
+ sLog.outErrorDb("Item (Entry: %u) has wrong GemProperties (%u)",i,proto->GemProperties);
+
+ if(proto->FoodType >= MAX_PET_DIET)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has wrong FoodType value (%u)",i,proto->FoodType);
+ const_cast<ItemPrototype*>(proto)->FoodType = 0;
+ }
+ }
+
+ // this DBC used currently only for check item templates in DB.
+ sItemStore.Clear();
+}
+
+void ObjectMgr::LoadAuctionItems()
+{
+ QueryResult *result = CharacterDatabase.Query( "SELECT itemguid,item_template FROM auctionhouse" );
+
+ if( !result )
+ return;
+
+ barGoLink bar( result->GetRowCount() );
+
+ uint32 count = 0;
+
+ Field *fields;
+ do
+ {
+ bar.step();
+
+ fields = result->Fetch();
+ uint32 item_guid = fields[0].GetUInt32();
+ uint32 item_template = fields[1].GetUInt32();
+
+ ItemPrototype const *proto = GetItemPrototype(item_template);
+
+ if(!proto)
+ {
+ sLog.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template);
+ continue;
+ }
+
+ Item *item = NewItemOrBag(proto);
+
+ if(!item->LoadFromDB(item_guid,0))
+ {
+ delete item;
+ continue;
+ }
+ AddAItem(item);
+
+ ++count;
+ }
+ while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u auction items", count );
+}
+
+void ObjectMgr::LoadPetLevelInfo()
+{
+ // Loading levels data
+ {
+ // 0 1 2 3 4 5 6 7 8 9
+ QueryResult *result = WorldDatabase.Query("SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u level pet stats definitions", count );
+ sLog.outErrorDb( "Error loading `pet_levelstats` table or empty table.");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 creature_id = fields[0].GetUInt32();
+ if(!sCreatureStorage.LookupEntry<CreatureInfo>(creature_id))
+ {
+ sLog.outErrorDb("Wrong creature id %u in `pet_levelstats` table, ignoring.",creature_id);
+ continue;
+ }
+
+ uint32 current_level = fields[1].GetUInt32();
+ if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ if(current_level > 255) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> 255) level %u in `pet_levelstats` table, ignoring.",current_level);
+ else
+ sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `pet_levelstats` table, ignoring.",current_level);
+ continue;
+ }
+ else if(current_level < 1)
+ {
+ sLog.outErrorDb("Wrong (<1) level %u in `pet_levelstats` table, ignoring.",current_level);
+ continue;
+ }
+
+ PetLevelInfo*& pInfoMapEntry = petInfo[creature_id];
+
+ if(pInfoMapEntry==NULL)
+ pInfoMapEntry = new PetLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)];
+
+ // data for level 1 stored in [0] array element, ...
+ PetLevelInfo* pLevelInfo = &pInfoMapEntry[current_level-1];
+
+ pLevelInfo->health = fields[2].GetUInt16();
+ pLevelInfo->mana = fields[3].GetUInt16();
+ pLevelInfo->armor = fields[9].GetUInt16();
+
+ for (int i = 0; i < MAX_STATS; i++)
+ {
+ pLevelInfo->stats[i] = fields[i+4].GetUInt16();
+ }
+
+ bar.step();
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u level pet stats definitions", count );
+ }
+
+ // Fill gaps and check integrity
+ for (PetLevelInfoMap::iterator itr = petInfo.begin(); itr != petInfo.end(); ++itr)
+ {
+ PetLevelInfo* pInfo = itr->second;
+
+ // fatal error if no level 1 data
+ if(!pInfo || pInfo[0].health == 0 )
+ {
+ sLog.outErrorDb("Creature %u does not have pet stats data for Level 1!",itr->first);
+ exit(1);
+ }
+
+ // fill level gaps
+ for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ {
+ if(pInfo[level].health == 0)
+ {
+ sLog.outErrorDb("Creature %u has no data for Level %i pet stats data, using data of Level %i.",itr->first,level+1, level);
+ pInfo[level] = pInfo[level-1];
+ }
+ }
+ }
+}
+
+PetLevelInfo const* ObjectMgr::GetPetLevelInfo(uint32 creature_id, uint32 level) const
+{
+ if(level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
+
+ PetLevelInfoMap::const_iterator itr = petInfo.find(creature_id);
+ if(itr == petInfo.end())
+ return NULL;
+
+ return &itr->second[level-1]; // data for level 1 stored in [0] array element, ...
+}
+
+void ObjectMgr::LoadPlayerInfo()
+{
+ // Load playercreate
+ {
+ // 0 1 2 3 4 5 6
+ QueryResult *result = WorldDatabase.Query("SELECT race, class, map, zone, position_x, position_y, position_z FROM playercreateinfo");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create definitions", count );
+ sLog.outErrorDb( "Error loading `playercreateinfo` table or empty table.");
+ exit(1);
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_race = fields[0].GetUInt32();
+ uint32 current_class = fields[1].GetUInt32();
+ uint32 mapId = fields[2].GetUInt32();
+ uint32 zoneId = fields[3].GetUInt32();
+ float positionX = fields[4].GetFloat();
+ float positionY = fields[5].GetFloat();
+ float positionZ = fields[6].GetFloat();
+
+ if(current_race >= MAX_RACES)
+ {
+ sLog.outErrorDb("Wrong race %u in `playercreateinfo` table, ignoring.",current_race);
+ continue;
+ }
+
+ ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(current_race);
+ if(!rEntry)
+ {
+ sLog.outErrorDb("Wrong race %u in `playercreateinfo` table, ignoring.",current_race);
+ continue;
+ }
+
+ if(current_class >= MAX_CLASSES)
+ {
+ sLog.outErrorDb("Wrong class %u in `playercreateinfo` table, ignoring.",current_class);
+ continue;
+ }
+
+ if(!sChrClassesStore.LookupEntry(current_class))
+ {
+ sLog.outErrorDb("Wrong class %u in `playercreateinfo` table, ignoring.",current_class);
+ continue;
+ }
+
+ // accept DB data only for valid position (and non instanceable)
+ if( !MapManager::IsValidMapCoord(mapId,positionX,positionY,positionZ) )
+ {
+ sLog.outErrorDb("Wrong home position for class %u race %u pair in `playercreateinfo` table, ignoring.",current_class,current_race);
+ continue;
+ }
+
+ if( sMapStore.LookupEntry(mapId)->Instanceable() )
+ {
+ sLog.outErrorDb("Home position in instanceable map for class %u race %u pair in `playercreateinfo` table, ignoring.",current_class,current_race);
+ continue;
+ }
+
+ PlayerInfo* pInfo = &playerInfo[current_race][current_class];
+
+ pInfo->mapId = mapId;
+ pInfo->zoneId = zoneId;
+ pInfo->positionX = positionX;
+ pInfo->positionY = positionY;
+ pInfo->positionZ = positionZ;
+
+ pInfo->displayId_m = rEntry->model_m;
+ pInfo->displayId_f = rEntry->model_f;
+
+ bar.step();
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create definitions", count );
+ }
+
+ // Load playercreate items
+ {
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT race, class, itemid, amount FROM playercreateinfo_item");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create items", count );
+ sLog.outErrorDb( "Error loading `playercreateinfo_item` table or empty table.");
+ }
+ else
+ {
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_race = fields[0].GetUInt32();
+ if(current_race >= MAX_RACES)
+ {
+ sLog.outErrorDb("Wrong race %u in `playercreateinfo_item` table, ignoring.",current_race);
+ continue;
+ }
+
+ uint32 current_class = fields[1].GetUInt32();
+ if(current_class >= MAX_CLASSES)
+ {
+ sLog.outErrorDb("Wrong class %u in `playercreateinfo_item` table, ignoring.",current_class);
+ continue;
+ }
+
+ PlayerInfo* pInfo = &playerInfo[current_race][current_class];
+
+ uint32 item_id = fields[2].GetUInt32();
+
+ if(!GetItemPrototype(item_id))
+ {
+ sLog.outErrorDb("Item id %u (race %u class %u) in `playercreateinfo_item` table but not listed in `item_template`, ignoring.",item_id,current_race,current_class);
+ continue;
+ }
+
+ uint32 amount = fields[3].GetUInt32();
+
+ if(!amount)
+ {
+ sLog.outErrorDb("Item id %u (class %u race %u) have amount==0 in `playercreateinfo_item` table, ignoring.",item_id,current_race,current_class);
+ continue;
+ }
+
+ pInfo->item.push_back(PlayerCreateInfoItem( item_id, amount));
+
+ bar.step();
+ ++count;
+ }
+ while(result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create items", count );
+ }
+ }
+
+ // Load playercreate spells
+ {
+
+ QueryResult *result = NULL;
+ if(sWorld.getConfig(CONFIG_START_ALL_SPELLS))
+ result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell_custom");
+ else
+ result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create spells", count );
+ sLog.outErrorDb( "Error loading player starting spells or empty table.");
+ }
+ else
+ {
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_race = fields[0].GetUInt32();
+ if(current_race >= MAX_RACES)
+ {
+ sLog.outErrorDb("Wrong race %u in `playercreateinfo_spell` table, ignoring.",current_race);
+ continue;
+ }
+
+ uint32 current_class = fields[1].GetUInt32();
+ if(current_class >= MAX_CLASSES)
+ {
+ sLog.outErrorDb("Wrong class %u in `playercreateinfo_spell` table, ignoring.",current_class);
+ continue;
+ }
+
+ PlayerInfo* pInfo = &playerInfo[current_race][current_class];
+ pInfo->spell.push_back(CreateSpellPair(fields[2].GetUInt16(), fields[3].GetUInt8()));
+
+ bar.step();
+ ++count;
+ }
+ while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create spells", count );
+ }
+ }
+
+ // Load playercreate actions
+ {
+ // 0 1 2 3 4 5
+ QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type, misc FROM playercreateinfo_action");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create actions", count );
+ sLog.outErrorDb( "Error loading `playercreateinfo_action` table or empty table.");
+ }
+ else
+ {
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_race = fields[0].GetUInt32();
+ if(current_race >= MAX_RACES)
+ {
+ sLog.outErrorDb("Wrong race %u in `playercreateinfo_action` table, ignoring.",current_race);
+ continue;
+ }
+
+ uint32 current_class = fields[1].GetUInt32();
+ if(current_class >= MAX_CLASSES)
+ {
+ sLog.outErrorDb("Wrong class %u in `playercreateinfo_action` table, ignoring.",current_class);
+ continue;
+ }
+
+ PlayerInfo* pInfo = &playerInfo[current_race][current_class];
+ pInfo->action[0].push_back(fields[2].GetUInt16());
+ pInfo->action[1].push_back(fields[3].GetUInt16());
+ pInfo->action[2].push_back(fields[4].GetUInt16());
+ pInfo->action[3].push_back(fields[5].GetUInt16());
+
+ bar.step();
+ ++count;
+ }
+ while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u player create actions", count );
+ }
+ }
+
+ // Loading levels data (class only dependent)
+ {
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u level health/mana definitions", count );
+ sLog.outErrorDb( "Error loading `player_classlevelstats` table or empty table.");
+ exit(1);
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_class = fields[0].GetUInt32();
+ if(current_class >= MAX_CLASSES)
+ {
+ sLog.outErrorDb("Wrong class %u in `player_classlevelstats` table, ignoring.",current_class);
+ continue;
+ }
+
+ uint32 current_level = fields[1].GetUInt32();
+ if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ if(current_level > 255) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> 255) level %u in `player_classlevelstats` table, ignoring.",current_level);
+ else
+ sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_classlevelstats` table, ignoring.",current_level);
+ continue;
+ }
+
+ PlayerClassInfo* pClassInfo = &playerClassInfo[current_class];
+
+ if(!pClassInfo->levelInfo)
+ pClassInfo->levelInfo = new PlayerClassLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)];
+
+ PlayerClassLevelInfo* pClassLevelInfo = &pClassInfo->levelInfo[current_level-1];
+
+ pClassLevelInfo->basehealth = fields[2].GetUInt16();
+ pClassLevelInfo->basemana = fields[3].GetUInt16();
+
+ bar.step();
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u level health/mana definitions", count );
+ }
+
+ // Fill gaps and check integrity
+ for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
+ {
+ // skip non existed classes
+ if(!sChrClassesStore.LookupEntry(class_))
+ continue;
+
+ PlayerClassInfo* pClassInfo = &playerClassInfo[class_];
+
+ // fatal error if no level 1 data
+ if(!pClassInfo->levelInfo || pClassInfo->levelInfo[0].basehealth == 0 )
+ {
+ sLog.outErrorDb("Class %i Level 1 does not have health/mana data!",class_);
+ exit(1);
+ }
+
+ // fill level gaps
+ for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ {
+ if(pClassInfo->levelInfo[level].basehealth == 0)
+ {
+ sLog.outErrorDb("Class %i Level %i does not have health/mana data. Using stats data of level %i.",class_,level+1, level);
+ pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level-1];
+ }
+ }
+ }
+
+ // Loading levels data (class/race dependent)
+ {
+ // 0 1 2 3 4 5 6 7
+ QueryResult *result = WorldDatabase.Query("SELECT race, class, level, str, agi, sta, inte, spi FROM player_levelstats");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u level stats definitions", count );
+ sLog.outErrorDb( "Error loading `player_levelstats` table or empty table.");
+ exit(1);
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_race = fields[0].GetUInt32();
+ if(current_race >= MAX_RACES)
+ {
+ sLog.outErrorDb("Wrong race %u in `player_levelstats` table, ignoring.",current_race);
+ continue;
+ }
+
+ uint32 current_class = fields[1].GetUInt32();
+ if(current_class >= MAX_CLASSES)
+ {
+ sLog.outErrorDb("Wrong class %u in `player_levelstats` table, ignoring.",current_class);
+ continue;
+ }
+
+ uint32 current_level = fields[2].GetUInt32();
+ if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ if(current_level > 255) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> 255) level %u in `player_levelstats` table, ignoring.",current_level);
+ else
+ sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_levelstats` table, ignoring.",current_level);
+ continue;
+ }
+
+ PlayerInfo* pInfo = &playerInfo[current_race][current_class];
+
+ if(!pInfo->levelInfo)
+ pInfo->levelInfo = new PlayerLevelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)];
+
+ PlayerLevelInfo* pLevelInfo = &pInfo->levelInfo[current_level-1];
+
+ for (int i = 0; i < MAX_STATS; i++)
+ {
+ pLevelInfo->stats[i] = fields[i+3].GetUInt8();
+ }
+
+ bar.step();
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u level stats definitions", count );
+ }
+
+ // Fill gaps and check integrity
+ for (int race = 0; race < MAX_RACES; ++race)
+ {
+ // skip non existed races
+ if(!sChrRacesStore.LookupEntry(race))
+ continue;
+
+ for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
+ {
+ // skip non existed classes
+ if(!sChrClassesStore.LookupEntry(class_))
+ continue;
+
+ PlayerInfo* pInfo = &playerInfo[race][class_];
+
+ // skip non loaded combinations
+ if(!pInfo->displayId_m || !pInfo->displayId_f)
+ continue;
+
+ // skip expansion races if not playing with expansion
+ if (sWorld.getConfig(CONFIG_EXPANSION) < 1 && (race == RACE_BLOODELF || race == RACE_DRAENEI))
+ continue;
+
+ // skip expansion classes if not playing with expansion
+ if (sWorld.getConfig(CONFIG_EXPANSION) < 2 && class_ == CLASS_DEATH_KNIGHT)
+ continue;
+
+ // fatal error if no level 1 data
+ if(!pInfo->levelInfo || pInfo->levelInfo[0].stats[0] == 0 )
+ {
+ sLog.outErrorDb("Race %i Class %i Level 1 does not have stats data!",race,class_);
+ exit(1);
+ }
+
+ // fill level gaps
+ for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ {
+ if(pInfo->levelInfo[level].stats[0] == 0)
+ {
+ sLog.outErrorDb("Race %i Class %i Level %i does not have stats data. Using stats data of level %i.",race,class_,level+1, level);
+ pInfo->levelInfo[level] = pInfo->levelInfo[level-1];
+ }
+ }
+ }
+ }
+}
+
+void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint32 level, PlayerClassLevelInfo* info) const
+{
+ if(level < 1 || class_ >= MAX_CLASSES)
+ return;
+
+ PlayerClassInfo const* pInfo = &playerClassInfo[class_];
+
+ if(level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
+
+ *info = pInfo->levelInfo[level-1];
+}
+
+void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint32 level, PlayerLevelInfo* info) const
+{
+ if(level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES)
+ return;
+
+ PlayerInfo const* pInfo = &playerInfo[race][class_];
+ if(pInfo->displayId_m==0 || pInfo->displayId_f==0)
+ return;
+
+ if(level <= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ *info = pInfo->levelInfo[level-1];
+ else
+ BuildPlayerLevelInfo(race,class_,level,info);
+}
+
+void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, PlayerLevelInfo* info) const
+{
+ // base data (last known level)
+ *info = playerInfo[race][_class].levelInfo[sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)-1];
+
+ for(int lvl = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)-1; lvl < level; ++lvl)
+ {
+ switch(_class)
+ {
+ case CLASS_WARRIOR:
+ info->stats[STAT_STRENGTH] += (lvl > 23 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_STAMINA] += (lvl > 23 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_AGILITY] += (lvl > 36 ? 1: (lvl > 6 && (lvl%2) ? 1: 0));
+ info->stats[STAT_INTELLECT] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_SPIRIT] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ break;
+ case CLASS_PALADIN:
+ info->stats[STAT_STRENGTH] += (lvl > 3 ? 1: 0);
+ info->stats[STAT_STAMINA] += (lvl > 33 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_AGILITY] += (lvl > 38 ? 1: (lvl > 7 && !(lvl%2) ? 1: 0));
+ info->stats[STAT_INTELLECT] += (lvl > 6 && (lvl%2) ? 1: 0);
+ info->stats[STAT_SPIRIT] += (lvl > 7 ? 1: 0);
+ break;
+ case CLASS_HUNTER:
+ info->stats[STAT_STRENGTH] += (lvl > 4 ? 1: 0);
+ info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0);
+ info->stats[STAT_AGILITY] += (lvl > 33 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_INTELLECT] += (lvl > 8 && (lvl%2) ? 1: 0);
+ info->stats[STAT_SPIRIT] += (lvl > 38 ? 1: (lvl > 9 && !(lvl%2) ? 1: 0));
+ break;
+ case CLASS_ROGUE:
+ info->stats[STAT_STRENGTH] += (lvl > 5 ? 1: 0);
+ info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0);
+ info->stats[STAT_AGILITY] += (lvl > 16 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_INTELLECT] += (lvl > 8 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_SPIRIT] += (lvl > 38 ? 1: (lvl > 9 && !(lvl%2) ? 1: 0));
+ break;
+ case CLASS_PRIEST:
+ info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_STAMINA] += (lvl > 5 ? 1: 0);
+ info->stats[STAT_AGILITY] += (lvl > 38 ? 1: (lvl > 8 && (lvl%2) ? 1: 0));
+ info->stats[STAT_INTELLECT] += (lvl > 22 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_SPIRIT] += (lvl > 3 ? 1: 0);
+ break;
+ case CLASS_SHAMAN:
+ info->stats[STAT_STRENGTH] += (lvl > 34 ? 1: (lvl > 6 && (lvl%2) ? 1: 0));
+ info->stats[STAT_STAMINA] += (lvl > 4 ? 1: 0);
+ info->stats[STAT_AGILITY] += (lvl > 7 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_INTELLECT] += (lvl > 5 ? 1: 0);
+ info->stats[STAT_SPIRIT] += (lvl > 4 ? 1: 0);
+ break;
+ case CLASS_MAGE:
+ info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_STAMINA] += (lvl > 5 ? 1: 0);
+ info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_INTELLECT] += (lvl > 24 ? 2: (lvl > 1 ? 1: 0));
+ info->stats[STAT_SPIRIT] += (lvl > 33 ? 2: (lvl > 2 ? 1: 0));
+ break;
+ case CLASS_WARLOCK:
+ info->stats[STAT_STRENGTH] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_STAMINA] += (lvl > 38 ? 2: (lvl > 3 ? 1: 0));
+ info->stats[STAT_AGILITY] += (lvl > 9 && !(lvl%2) ? 1: 0);
+ info->stats[STAT_INTELLECT] += (lvl > 33 ? 2: (lvl > 2 ? 1: 0));
+ info->stats[STAT_SPIRIT] += (lvl > 38 ? 2: (lvl > 3 ? 1: 0));
+ break;
+ case CLASS_DRUID:
+ info->stats[STAT_STRENGTH] += (lvl > 38 ? 2: (lvl > 6 && (lvl%2) ? 1: 0));
+ info->stats[STAT_STAMINA] += (lvl > 32 ? 2: (lvl > 4 ? 1: 0));
+ info->stats[STAT_AGILITY] += (lvl > 38 ? 2: (lvl > 8 && (lvl%2) ? 1: 0));
+ info->stats[STAT_INTELLECT] += (lvl > 38 ? 3: (lvl > 4 ? 1: 0));
+ info->stats[STAT_SPIRIT] += (lvl > 38 ? 3: (lvl > 5 ? 1: 0));
+ }
+ }
+}
+
+void ObjectMgr::LoadGuilds()
+{
+ Guild *newguild;
+ uint32 count = 0;
+
+ QueryResult *result = CharacterDatabase.Query( "SELECT guildid FROM guild" );
+
+ if( !result )
+ {
+
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u guild definitions", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar.step();
+ ++count;
+
+ newguild = new Guild;
+ if(!newguild->LoadGuildFromDB(fields[0].GetUInt32()))
+ {
+ newguild->Disband();
+ delete newguild;
+ continue;
+ }
+ AddGuild(newguild);
+
+ }while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u guild definitions", count );
+}
+
+void ObjectMgr::LoadArenaTeams()
+{
+ uint32 count = 0;
+
+ QueryResult *result = CharacterDatabase.Query( "SELECT arenateamid FROM arena_team" );
+
+ if( !result )
+ {
+
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u arenateam definitions", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar.step();
+ ++count;
+
+ ArenaTeam *newarenateam = new ArenaTeam;
+ if(!newarenateam->LoadArenaTeamFromDB(fields[0].GetUInt32()))
+ {
+ delete newarenateam;
+ continue;
+ }
+ AddArenaTeam(newarenateam);
+ }while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u arenateam definitions", count );
+}
+
+void ObjectMgr::LoadGroups()
+{
+ // -- loading groups --
+ Group *group = NULL;
+ uint64 leaderGuid = 0;
+ uint32 count = 0;
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ QueryResult *result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u group definitions", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ ++count;
+ leaderGuid = MAKE_NEW_GUID(fields[15].GetUInt32(),0,HIGHGUID_PLAYER);
+
+ group = new Group;
+ if(!group->LoadGroupFromDB(leaderGuid, result, false))
+ {
+ group->Disband();
+ delete group;
+ continue;
+ }
+ AddGroup(group);
+ }while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u group definitions", count );
+
+ // -- loading members --
+ count = 0;
+ group = NULL;
+ leaderGuid = 0;
+ // 0 1 2 3
+ result = CharacterDatabase.Query("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid");
+ if(!result)
+ {
+ barGoLink bar( 1 );
+ bar.step();
+ }
+ else
+ {
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ count++;
+ leaderGuid = MAKE_NEW_GUID(fields[3].GetUInt32(), 0, HIGHGUID_PLAYER);
+ if(!group || group->GetLeaderGUID() != leaderGuid)
+ {
+ group = GetGroupByLeader(leaderGuid);
+ if(!group)
+ {
+ sLog.outErrorDb("Incorrect entry in group_member table : no group with leader %d for member %d!", fields[3].GetUInt32(), fields[0].GetUInt32());
+ CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid = '%d'", fields[0].GetUInt32());
+ continue;
+ }
+ }
+
+ if(!group->LoadMemberFromDB(fields[0].GetUInt32(), fields[2].GetUInt8(), fields[1].GetBool()))
+ {
+ sLog.outErrorDb("Incorrect entry in group_member table : member %d cannot be added to player %d's group!", fields[0].GetUInt32(), fields[3].GetUInt32());
+ CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid = '%d'", fields[0].GetUInt32());
+ }
+ }while( result->NextRow() );
+ delete result;
+ }
+
+ // clean groups
+ // TODO: maybe delete from the DB before loading in this case
+ for(GroupSet::iterator itr = mGroupSet.begin(); itr != mGroupSet.end();)
+ {
+ if((*itr)->GetMembersCount() < 2)
+ {
+ (*itr)->Disband();
+ delete *itr;
+ mGroupSet.erase(itr++);
+ }
+ else
+ ++itr;
+ }
+
+ // -- loading instances --
+ count = 0;
+ group = NULL;
+ leaderGuid = 0;
+ result = CharacterDatabase.Query(
+ // 0 1 2 3 4 5
+ "SELECT leaderGuid, map, instance, permanent, difficulty, resettime, "
+ // 6
+ "(SELECT COUNT(*) FROM character_instance WHERE guid = leaderGuid AND instance = group_instance.instance AND permanent = 1 LIMIT 1) "
+ "FROM group_instance LEFT JOIN instance ON instance = id ORDER BY leaderGuid"
+ );
+
+ if(!result)
+ {
+ barGoLink bar( 1 );
+ bar.step();
+ }
+ else
+ {
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ count++;
+ leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ if(!group || group->GetLeaderGUID() != leaderGuid)
+ {
+ group = GetGroupByLeader(leaderGuid);
+ if(!group)
+ {
+ sLog.outErrorDb("Incorrect entry in group_instance table : no group with leader %d", fields[0].GetUInt32());
+ continue;
+ }
+ }
+
+ InstanceSave *save = sInstanceSaveManager.AddInstanceSave(fields[1].GetUInt32(), fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true);
+ group->BindToInstance(save, fields[3].GetBool(), true);
+ }while( result->NextRow() );
+ delete result;
+ }
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u group-instance binds total", count );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u group members total", count );
+}
+
+void ObjectMgr::LoadQuests()
+{
+ // For reload case
+ for(QuestMap::const_iterator itr=mQuestTemplates.begin(); itr != mQuestTemplates.end(); ++itr)
+ delete itr->second;
+ mQuestTemplates.clear();
+
+ mExclusiveQuestGroups.clear();
+
+ // 0 1 2 3 4 5 6 7 8
+ QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
+ // 9 10 11 12 13 14 15 16
+ "RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime,"
+ // 17 18 19 20 21 22 23 24 25 26
+ "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
+ // 27 28 29 30 31 32 33 34 35 36
+ "Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
+ // 37 38 39 40 41 42 43 44
+ "ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4,"
+ // 45 46 47 48 49 50 51 52 53 54 54 55
+ "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4,"
+ // 57 58 59 60 61 62 63 64
+ "ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
+ // 65 66 67 68
+ "ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
+ // 69 70 71 72 73 74
+ "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
+ // 75 76 77 78 79 80
+ "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6,"
+ // 81 82 83 84 85 86 87 88
+ "RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
+ // 89 90 91 92 93 94 95 96 97 98
+ "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
+ // 99 100 101 102 103 104 105 106 107 108 109
+ "RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
+ // 110 111 112 113 114 115 116 117 118 119
+ "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
+ // 120 121
+ "StartScript, CompleteScript"
+ " FROM quest_template");
+ if(result == NULL)
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded 0 quests definitions" );
+ sLog.outErrorDb("`quest_template` table is empty!");
+ return;
+ }
+
+ // create multimap previous quest for each existed quest
+ // some quests can have many previous maps set by NextQuestId in previous quest
+ // for example set of race quests can lead to single not race specific quest
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+
+ Quest * newQuest = new Quest(fields);
+ mQuestTemplates[newQuest->GetQuestId()] = newQuest;
+ } while( result->NextRow() );
+
+ delete result;
+
+ // Post processing
+ for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); iter++)
+ {
+ Quest * qinfo = iter->second;
+
+ // additional quest integrity checks (GO, creature_template and item_template must be loaded already)
+
+ if( qinfo->GetQuestMethod() >= 3 )
+ {
+ sLog.outErrorDb("Quest %u has `Method` = %u, expected values are 0, 1 or 2.",qinfo->GetQuestId(),qinfo->GetQuestMethod());
+ }
+
+ if (qinfo->QuestFlags & ~QUEST_TRINITY_FLAGS_DB_ALLOWED)
+ {
+ sLog.outErrorDb("Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u",
+ qinfo->GetQuestId(),qinfo->QuestFlags,QUEST_TRINITY_FLAGS_DB_ALLOWED >> 16);
+ qinfo->QuestFlags &= QUEST_TRINITY_FLAGS_DB_ALLOWED;
+ }
+
+ if(qinfo->QuestFlags & QUEST_FLAGS_DAILY)
+ {
+ if(!(qinfo->QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE))
+ {
+ sLog.outErrorDb("Daily Quest %u not marked as repeatable in `SpecialFlags`, added.",qinfo->GetQuestId());
+ qinfo->QuestFlags |= QUEST_TRINITY_FLAGS_REPEATABLE;
+ }
+ }
+
+ if(qinfo->QuestFlags & QUEST_FLAGS_AUTO_REWARDED)
+ {
+ // at auto-reward can be rewarded only RewChoiceItemId[0]
+ for(int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )
+ {
+ if(uint32 id = qinfo->RewChoiceItemId[j])
+ {
+ sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but item from `RewChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_AUTO_REWARDED.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ // no changes, quest ignore this data
+ }
+ }
+ }
+
+ // client quest log visual (area case)
+ if( qinfo->ZoneOrSort > 0 )
+ {
+ if(!GetAreaEntryByAreaID(qinfo->ZoneOrSort))
+ {
+ sLog.outErrorDb("Quest %u has `ZoneOrSort` = %u (zone case) but zone with this id does not exist.",
+ qinfo->GetQuestId(),qinfo->ZoneOrSort);
+ // no changes, quest not dependent from this value but can have problems at client
+ }
+ }
+ // client quest log visual (sort case)
+ if( qinfo->ZoneOrSort < 0 )
+ {
+ QuestSortEntry const* qSort = sQuestSortStore.LookupEntry(-int32(qinfo->ZoneOrSort));
+ if( !qSort )
+ {
+ sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (sort case) but quest sort with this id does not exist.",
+ qinfo->GetQuestId(),qinfo->ZoneOrSort);
+ // no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
+ }
+ //check SkillOrClass value (class case).
+ if( ClassByQuestSort(-int32(qinfo->ZoneOrSort)) )
+ {
+ // SkillOrClass should not have class case when class case already set in ZoneOrSort.
+ if(qinfo->SkillOrClass < 0)
+ {
+ sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (class sort case) and `SkillOrClass` = %i (class case), redundant.",
+ qinfo->GetQuestId(),qinfo->ZoneOrSort,qinfo->SkillOrClass);
+ }
+ }
+ //check for proper SkillOrClass value (skill case)
+ if(int32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
+ {
+ // skill is positive value in SkillOrClass
+ if(qinfo->SkillOrClass != skill_id )
+ {
+ sLog.outErrorDb("Quest %u has `ZoneOrSort` = %i (skill sort case) but `SkillOrClass` does not have a corresponding value (%i).",
+ qinfo->GetQuestId(),qinfo->ZoneOrSort,skill_id);
+ //override, and force proper value here?
+ }
+ }
+ }
+
+ // SkillOrClass (class case)
+ if( qinfo->SkillOrClass < 0 )
+ {
+ if( !sChrClassesStore.LookupEntry(-int32(qinfo->SkillOrClass)) )
+ {
+ sLog.outErrorDb("Quest %u has `SkillOrClass` = %i (class case) but class (%i) does not exist",
+ qinfo->GetQuestId(),qinfo->SkillOrClass,-qinfo->SkillOrClass);
+ }
+ }
+ // SkillOrClass (skill case)
+ if( qinfo->SkillOrClass > 0 )
+ {
+ if( !sSkillLineStore.LookupEntry(qinfo->SkillOrClass) )
+ {
+ sLog.outErrorDb("Quest %u has `SkillOrClass` = %u (skill case) but skill (%i) does not exist",
+ qinfo->GetQuestId(),qinfo->SkillOrClass,qinfo->SkillOrClass);
+ }
+ }
+
+ if( qinfo->RequiredSkillValue )
+ {
+ if( qinfo->RequiredSkillValue > sWorld.GetConfigMaxSkillValue() )
+ {
+ sLog.outErrorDb("Quest %u has `RequiredSkillValue` = %u but max possible skill is %u, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RequiredSkillValue,sWorld.GetConfigMaxSkillValue());
+ // no changes, quest can't be done for this requirement
+ }
+
+ if( qinfo->SkillOrClass <= 0 )
+ {
+ sLog.outErrorDb("Quest %u has `RequiredSkillValue` = %u but `SkillOrClass` = %i (class case), value ignored.",
+ qinfo->GetQuestId(),qinfo->RequiredSkillValue,qinfo->SkillOrClass);
+ // no changes, quest can't be done for this requirement (fail at wrong skill id)
+ }
+ }
+ // else Skill quests can have 0 skill level, this is ok
+
+ if(qinfo->RepObjectiveFaction && !sFactionStore.LookupEntry(qinfo->RepObjectiveFaction))
+ {
+ sLog.outErrorDb("Quest %u has `RepObjectiveFaction` = %u but faction template %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RepObjectiveFaction,qinfo->RepObjectiveFaction);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(qinfo->RequiredMinRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMinRepFaction))
+ {
+ sLog.outErrorDb("Quest %u has `RequiredMinRepFaction` = %u but faction template %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RequiredMinRepFaction,qinfo->RequiredMinRepFaction);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(qinfo->RequiredMaxRepFaction && !sFactionStore.LookupEntry(qinfo->RequiredMaxRepFaction))
+ {
+ sLog.outErrorDb("Quest %u has `RequiredMaxRepFaction` = %u but faction template %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RequiredMaxRepFaction,qinfo->RequiredMaxRepFaction);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(qinfo->RequiredMinRepValue && qinfo->RequiredMinRepValue > Player::Reputation_Cap)
+ {
+ sLog.outErrorDb("Quest %u has `RequiredMinRepValue` = %d but max reputation is %u, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RequiredMinRepValue,Player::Reputation_Cap);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(qinfo->RequiredMinRepValue && qinfo->RequiredMaxRepValue && qinfo->RequiredMaxRepValue <= qinfo->RequiredMinRepValue)
+ {
+ sLog.outErrorDb("Quest %u has `RequiredMaxRepValue` = %d and `RequiredMinRepValue` = %d, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RequiredMaxRepValue,qinfo->RequiredMinRepValue);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(!qinfo->RepObjectiveFaction && qinfo->RepObjectiveValue > 0 )
+ {
+ sLog.outErrorDb("Quest %u has `RepObjectiveValue` = %d but `RepObjectiveFaction` is 0, value has no effect",
+ qinfo->GetQuestId(),qinfo->RepObjectiveValue);
+ // warning
+ }
+
+ if(!qinfo->RequiredMinRepFaction && qinfo->RequiredMinRepValue > 0 )
+ {
+ sLog.outErrorDb("Quest %u has `RequiredMinRepValue` = %d but `RequiredMinRepFaction` is 0, value has no effect",
+ qinfo->GetQuestId(),qinfo->RequiredMinRepValue);
+ // warning
+ }
+
+ if(!qinfo->RequiredMaxRepFaction && qinfo->RequiredMaxRepValue > 0 )
+ {
+ sLog.outErrorDb("Quest %u has `RequiredMaxRepValue` = %d but `RequiredMaxRepFaction` is 0, value has no effect",
+ qinfo->GetQuestId(),qinfo->RequiredMaxRepValue);
+ // warning
+ }
+
+ if(qinfo->CharTitleId && !sCharTitlesStore.LookupEntry(qinfo->CharTitleId))
+ {
+ sLog.outErrorDb("Quest %u has `CharTitleId` = %u but CharTitle Id %u does not exist, quest can't be rewarded with title.",
+ qinfo->GetQuestId(),qinfo->GetCharTitleId(),qinfo->GetCharTitleId());
+ qinfo->CharTitleId = 0;
+ // quest can't reward this title
+ }
+
+ if(qinfo->SrcItemId)
+ {
+ if(!sItemStorage.LookupEntry<ItemPrototype>(qinfo->SrcItemId))
+ {
+ sLog.outErrorDb("Quest %u has `SrcItemId` = %u but item with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->SrcItemId,qinfo->SrcItemId);
+ qinfo->SrcItemId = 0; // quest can't be done for this requirement
+ }
+ else if(qinfo->SrcItemCount==0)
+ {
+ sLog.outErrorDb("Quest %u has `SrcItemId` = %u but `SrcItemCount` = 0, set to 1 but need fix in DB.",
+ qinfo->GetQuestId(),qinfo->SrcItemId);
+ qinfo->SrcItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB
+ }
+ }
+ else if(qinfo->SrcItemCount>0)
+ {
+ sLog.outErrorDb("Quest %u has `SrcItemId` = 0 but `SrcItemCount` = %u, useless value.",
+ qinfo->GetQuestId(),qinfo->SrcItemCount);
+ qinfo->SrcItemCount=0; // no quest work changes in fact
+ }
+
+ if(qinfo->SrcSpell)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->SrcSpell);
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Quest %u has `SrcSpell` = %u but spell %u doesn't exist, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->SrcSpell,qinfo->SrcSpell);
+ qinfo->SrcSpell = 0; // quest can't be done for this requirement
+ }
+ else if(!SpellMgr::IsSpellValid(spellInfo))
+ {
+ sLog.outErrorDb("Quest %u has `SrcSpell` = %u but spell %u is broken, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->SrcSpell,qinfo->SrcSpell);
+ qinfo->SrcSpell = 0; // quest can't be done for this requirement
+ }
+ }
+
+ for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j )
+ {
+ uint32 id = qinfo->ReqItemId[j];
+ if(id)
+ {
+ if(qinfo->ReqItemCount[j]==0)
+ {
+ sLog.outErrorDb("Quest %u has `ReqItemId%d` = %u but `ReqItemCount%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ // no changes, quest can't be done for this requirement
+ }
+
+ qinfo->SetFlag(QUEST_TRINITY_FLAGS_DELIVER);
+
+ if(!sItemStorage.LookupEntry<ItemPrototype>(id))
+ {
+ sLog.outErrorDb("Quest %u has `ReqItemId%d` = %u but item with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,id);
+ qinfo->ReqItemCount[j] = 0; // prevent incorrect work of quest
+ }
+ }
+ else if(qinfo->ReqItemCount[j]>0)
+ {
+ sLog.outErrorDb("Quest %u has `ReqItemId%d` = 0 but `ReqItemCount%d` = %u, quest can't be done.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->ReqItemCount[j]);
+ qinfo->ReqItemCount[j] = 0; // prevent incorrect work of quest
+ }
+ }
+
+ for(int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j )
+ {
+ uint32 id = qinfo->ReqSourceId[j];
+ if(id)
+ {
+ if(!sItemStorage.LookupEntry<ItemPrototype>(id))
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but item with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,id);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(!qinfo->ReqSourceCount[j])
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but `ReqSourceCount%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest
+ }
+
+ if(!qinfo->ReqSourceRef[j])
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceId%d` = %u but `ReqSourceRef%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest
+ }
+ }
+ else
+ {
+ if(qinfo->ReqSourceCount[j]>0)
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceId%d` = 0 but `ReqSourceCount%d` = %u.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->ReqSourceCount[j]);
+ // no changes, quest ignore this data
+ }
+
+ if(qinfo->ReqSourceRef[j]>0)
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceId%d` = 0 but `ReqSourceRef%d` = %u.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->ReqSourceRef[j]);
+ // no changes, quest ignore this data
+ }
+ }
+ }
+
+ for(int j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j )
+ {
+ uint32 ref = qinfo->ReqSourceRef[j];
+ if(ref)
+ {
+ if(ref > QUEST_OBJECTIVES_COUNT)
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceRef%d` = %u but max value in `ReqSourceRef%d` is %u, quest can't be done.",
+ qinfo->GetQuestId(),j+1,ref,j+1,QUEST_OBJECTIVES_COUNT);
+ // no changes, quest can't be done for this requirement
+ }
+ else
+ if(!qinfo->ReqItemId[ref-1] && !qinfo->ReqSpell[ref-1])
+ {
+ sLog.outErrorDb("Quest %u has `ReqSourceRef%d` = %u but `ReqItemId%u` = 0 and `ReqSpellCast%u` = 0, quest can't be done.",
+ qinfo->GetQuestId(),j+1,ref,ref,ref);
+ // no changes, quest can't be done for this requirement
+ }
+ else if(qinfo->ReqItemId[ref-1] && qinfo->ReqSpell[ref-1])
+ {
+ sLog.outErrorDb("Quest %u has `ReqItemId%u` = %u and `ReqSpellCast%u` = %u, quest can't have both fields <> 0, then can't be done.",
+ qinfo->GetQuestId(),ref,qinfo->ReqItemId[ref-1],ref,qinfo->ReqSpell[ref-1]);
+ // no changes, quest can't be done for this requirement
+ qinfo->ReqSourceId[j] = 0; // prevent incorrect work of quest
+ }
+ }
+ }
+
+ for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j )
+ {
+ uint32 id = qinfo->ReqSpell[j];
+ if(id)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Quest %u has `ReqSpellCast%d` = %u but spell %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,id);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if(!qinfo->ReqCreatureOrGOId[j])
+ {
+ bool found = false;
+ for(int k = 0; k < 3; ++k)
+ {
+ if( spellInfo->Effect[k]==SPELL_EFFECT_QUEST_COMPLETE && uint32(spellInfo->EffectMiscValue[k])==qinfo->QuestId ||
+ spellInfo->Effect[k]==SPELL_EFFECT_SEND_EVENT)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if(found)
+ {
+ if(!qinfo->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
+ {
+ sLog.outErrorDb("Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT for quest %u and ReqCreatureOrGOId%d = 0, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Quest flags or ReqCreatureOrGOId%d must be fixed, quest modified to enable objective.",spellInfo->Id,qinfo->QuestId,j+1,j+1);
+
+ // this will prevent quest completing without objective
+ const_cast<Quest*>(qinfo)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
+ }
+ }
+ else
+ {
+ sLog.outErrorDb("Quest %u has `ReqSpellCast%d` = %u and ReqCreatureOrGOId%d = 0 but spell %u does not have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT effect for this quest, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,j+1,id);
+ // no changes, quest can't be done for this requirement
+ }
+ }
+ }
+ }
+
+ for(int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j )
+ {
+ int32 id = qinfo->ReqCreatureOrGOId[j];
+ if(id < 0 && !sGOStorage.LookupEntry<GameObjectInfo>(-id))
+ {
+ sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %i but gameobject %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,uint32(-id));
+ qinfo->ReqCreatureOrGOId[j] = 0; // quest can't be done for this requirement
+ }
+
+ if(id > 0 && !sCreatureStorage.LookupEntry<CreatureInfo>(id))
+ {
+ sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %i but creature with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,uint32(id));
+ qinfo->ReqCreatureOrGOId[j] = 0; // quest can't be done for this requirement
+ }
+
+ if(id)
+ {
+ // In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
+
+ qinfo->SetFlag(QUEST_TRINITY_FLAGS_KILL_OR_CAST | QUEST_TRINITY_FLAGS_SPEAKTO);
+
+ if(!qinfo->ReqCreatureOrGOCount[j])
+ {
+ sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = %u but `ReqCreatureOrGOCount%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ // no changes, quest can be incorrectly done, but we already report this
+ }
+ }
+ else if(qinfo->ReqCreatureOrGOCount[j]>0)
+ {
+ sLog.outErrorDb("Quest %u has `ReqCreatureOrGOId%d` = 0 but `ReqCreatureOrGOCount%d` = %u.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->ReqCreatureOrGOCount[j]);
+ // no changes, quest ignore this data
+ }
+ }
+
+ for(int j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j )
+ {
+ uint32 id = qinfo->RewChoiceItemId[j];
+ if(id)
+ {
+ if(!sItemStorage.LookupEntry<ItemPrototype>(id))
+ {
+ sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.",
+ qinfo->GetQuestId(),j+1,id,id);
+ qinfo->RewChoiceItemId[j] = 0; // no changes, quest will not reward this
+ }
+
+ if(!qinfo->RewChoiceItemCount[j])
+ {
+ sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = %u but `RewChoiceItemCount%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ // no changes, quest can't be done
+ }
+ }
+ else if(qinfo->RewChoiceItemCount[j]>0)
+ {
+ sLog.outErrorDb("Quest %u has `RewChoiceItemId%d` = 0 but `RewChoiceItemCount%d` = %u.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->RewChoiceItemCount[j]);
+ // no changes, quest ignore this data
+ }
+ }
+
+ for(int j = 0; j < QUEST_REWARDS_COUNT; ++j )
+ {
+ uint32 id = qinfo->RewItemId[j];
+ if(id)
+ {
+ if(!sItemStorage.LookupEntry<ItemPrototype>(id))
+ {
+ sLog.outErrorDb("Quest %u has `RewItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.",
+ qinfo->GetQuestId(),j+1,id,id);
+ qinfo->RewItemId[j] = 0; // no changes, quest will not reward this item
+ }
+
+ if(!qinfo->RewItemCount[j])
+ {
+ sLog.outErrorDb("Quest %u has `RewItemId%d` = %u but `RewItemCount%d` = 0, quest will not reward this item.",
+ qinfo->GetQuestId(),j+1,id,j+1);
+ // no changes
+ }
+ }
+ else if(qinfo->RewItemCount[j]>0)
+ {
+ sLog.outErrorDb("Quest %u has `RewItemId%d` = 0 but `RewItemCount%d` = %u.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->RewItemCount[j]);
+ // no changes, quest ignore this data
+ }
+ }
+
+ for(int j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
+ {
+ if(qinfo->RewRepFaction[j])
+ {
+ if(!qinfo->RewRepValue[j])
+ {
+ sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but `RewRepValue%d` = 0, quest will not reward this reputation.",
+ qinfo->GetQuestId(),j+1,qinfo->RewRepValue[j],j+1);
+ // no changes
+ }
+
+ if(!sFactionStore.LookupEntry(qinfo->RewRepFaction[j]))
+ {
+ sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but raw faction (faction.dbc) %u does not exist, quest will not reward reputation for this faction.",
+ qinfo->GetQuestId(),j+1,qinfo->RewRepFaction[j] ,qinfo->RewRepFaction[j] );
+ qinfo->RewRepFaction[j] = 0; // quest will not reward this
+ }
+ }
+ else if(qinfo->RewRepValue[j]!=0)
+ {
+ sLog.outErrorDb("Quest %u has `RewRepFaction%d` = 0 but `RewRepValue%d` = %u.",
+ qinfo->GetQuestId(),j+1,j+1,qinfo->RewRepValue[j]);
+ // no changes, quest ignore this data
+ }
+ }
+
+ if(qinfo->RewSpell)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpell);
+
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u does not exist, spell removed as display reward.",
+ qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
+ qinfo->RewSpell = 0; // no spell reward will display for this quest
+ }
+
+ else if(!SpellMgr::IsSpellValid(spellInfo))
+ {
+ sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is broken, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell);
+ qinfo->RewSpell = 0; // no spell reward will display for this quest
+ }
+
+ }
+
+ if(qinfo->RewSpellCast)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpellCast);
+
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.",
+ qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
+ qinfo->RewSpellCast = 0; // no spell will be casted on player
+ }
+
+ else if(!SpellMgr::IsSpellValid(spellInfo))
+ {
+ sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u is broken, quest can't be done.",
+ qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast);
+ qinfo->RewSpellCast = 0; // no spell will be casted on player
+ }
+
+ }
+
+ if(qinfo->RewMailTemplateId)
+ {
+ if(!sMailTemplateStore.LookupEntry(qinfo->RewMailTemplateId))
+ {
+ sLog.outErrorDb("Quest %u has `RewMailTemplateId` = %u but mail template %u does not exist, quest will not have a mail reward.",
+ qinfo->GetQuestId(),qinfo->RewMailTemplateId,qinfo->RewMailTemplateId);
+ qinfo->RewMailTemplateId = 0; // no mail will send to player
+ qinfo->RewMailDelaySecs = 0; // no mail will send to player
+ }
+ }
+
+ if(qinfo->NextQuestInChain)
+ {
+ if(mQuestTemplates.find(qinfo->NextQuestInChain) == mQuestTemplates.end())
+ {
+ sLog.outErrorDb("Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.",
+ qinfo->GetQuestId(),qinfo->NextQuestInChain ,qinfo->NextQuestInChain );
+ qinfo->NextQuestInChain = 0;
+ }
+ else
+ mQuestTemplates[qinfo->NextQuestInChain]->prevChainQuests.push_back(qinfo->GetQuestId());
+ }
+
+ // fill additional data stores
+ if(qinfo->PrevQuestId)
+ {
+ if (mQuestTemplates.find(abs(qinfo->GetPrevQuestId())) == mQuestTemplates.end())
+ {
+ sLog.outErrorDb("Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
+ }
+ else
+ {
+ qinfo->prevQuests.push_back(qinfo->PrevQuestId);
+ }
+ }
+
+ if(qinfo->NextQuestId)
+ {
+ if (mQuestTemplates.find(abs(qinfo->GetNextQuestId())) == mQuestTemplates.end())
+ {
+ sLog.outErrorDb("Quest %d has NextQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
+ }
+ else
+ {
+ int32 signedQuestId = qinfo->NextQuestId < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId());
+ mQuestTemplates[abs(qinfo->GetNextQuestId())]->prevQuests.push_back(signedQuestId);
+ }
+ }
+
+ if(qinfo->ExclusiveGroup)
+ mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
+ if(qinfo->LimitTime)
+ qinfo->SetFlag(QUEST_TRINITY_FLAGS_TIMED);
+ }
+
+ // check QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
+ for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(i);
+ if(!spellInfo)
+ continue;
+
+ for(int j = 0; j < 3; ++j)
+ {
+ if(spellInfo->Effect[j] != SPELL_EFFECT_QUEST_COMPLETE)
+ continue;
+
+ uint32 quest_id = spellInfo->EffectMiscValue[j];
+
+ Quest const* quest = GetQuestTemplate(quest_id);
+
+ // some quest referenced in spells not exist (outdated spells)
+ if(!quest)
+ continue;
+
+ if(!quest->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
+ {
+ sLog.outErrorDb("Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE for quest %u , but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Quest flags must be fixed, quest modified to enable objective.",spellInfo->Id,quest_id);
+
+ // this will prevent quest completing without objective
+ const_cast<Quest*>(quest)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
+ }
+ }
+ }
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u quests definitions", mQuestTemplates.size() );
+}
+
+void ObjectMgr::LoadQuestLocales()
+{
+ mQuestLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,"
+ "Title_loc1,Details_loc1,Objectives_loc1,OfferRewardText_loc1,RequestItemsText_loc1,EndText_loc1,ObjectiveText1_loc1,ObjectiveText2_loc1,ObjectiveText3_loc1,ObjectiveText4_loc1,"
+ "Title_loc2,Details_loc2,Objectives_loc2,OfferRewardText_loc2,RequestItemsText_loc2,EndText_loc2,ObjectiveText1_loc2,ObjectiveText2_loc2,ObjectiveText3_loc2,ObjectiveText4_loc2,"
+ "Title_loc3,Details_loc3,Objectives_loc3,OfferRewardText_loc3,RequestItemsText_loc3,EndText_loc3,ObjectiveText1_loc3,ObjectiveText2_loc3,ObjectiveText3_loc3,ObjectiveText4_loc3,"
+ "Title_loc4,Details_loc4,Objectives_loc4,OfferRewardText_loc4,RequestItemsText_loc4,EndText_loc4,ObjectiveText1_loc4,ObjectiveText2_loc4,ObjectiveText3_loc4,ObjectiveText4_loc4,"
+ "Title_loc5,Details_loc5,Objectives_loc5,OfferRewardText_loc5,RequestItemsText_loc5,EndText_loc5,ObjectiveText1_loc5,ObjectiveText2_loc5,ObjectiveText3_loc5,ObjectiveText4_loc5,"
+ "Title_loc6,Details_loc6,Objectives_loc6,OfferRewardText_loc6,RequestItemsText_loc6,EndText_loc6,ObjectiveText1_loc6,ObjectiveText2_loc6,ObjectiveText3_loc6,ObjectiveText4_loc6,"
+ "Title_loc7,Details_loc7,Objectives_loc7,OfferRewardText_loc7,RequestItemsText_loc7,EndText_loc7,ObjectiveText1_loc7,ObjectiveText2_loc7,ObjectiveText3_loc7,ObjectiveText4_loc7,"
+ "Title_loc8,Details_loc8,Objectives_loc8,OfferRewardText_loc8,RequestItemsText_loc8,EndText_loc8,ObjectiveText1_loc8,ObjectiveText2_loc8,ObjectiveText3_loc8,ObjectiveText4_loc8"
+ " FROM locales_quest"
+ );
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_quest` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ QuestLocale& data = mQuestLocaleMap[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[1+10*(i-1)].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Title.size() <= idx)
+ data.Title.resize(idx+1);
+
+ data.Title[idx] = str;
+ }
+ }
+ str = fields[1+10*(i-1)+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Details.size() <= idx)
+ data.Details.resize(idx+1);
+
+ data.Details[idx] = str;
+ }
+ }
+ str = fields[1+10*(i-1)+2].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Objectives.size() <= idx)
+ data.Objectives.resize(idx+1);
+
+ data.Objectives[idx] = str;
+ }
+ }
+ str = fields[1+10*(i-1)+3].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.OfferRewardText.size() <= idx)
+ data.OfferRewardText.resize(idx+1);
+
+ data.OfferRewardText[idx] = str;
+ }
+ }
+ str = fields[1+10*(i-1)+4].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.RequestItemsText.size() <= idx)
+ data.RequestItemsText.resize(idx+1);
+
+ data.RequestItemsText[idx] = str;
+ }
+ }
+ str = fields[1+10*(i-1)+5].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.EndText.size() <= idx)
+ data.EndText.resize(idx+1);
+
+ data.EndText[idx] = str;
+ }
+ }
+ for(int k = 0; k < 4; ++k)
+ {
+ str = fields[1+10*(i-1)+6+k].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.ObjectiveText[k].size() <= idx)
+ data.ObjectiveText[k].resize(idx+1);
+
+ data.ObjectiveText[k][idx] = str;
+ }
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u Quest locale strings", mQuestLocaleMap.size() );
+}
+
+void ObjectMgr::LoadPetCreateSpells()
+{
+ QueryResult *result = WorldDatabase.Query("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell");
+ if(!result)
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded 0 pet create spells" );
+ sLog.outErrorDb("`petcreateinfo_spell` table is empty!");
+ return;
+ }
+
+ uint32 count = 0;
+
+ barGoLink bar( result->GetRowCount() );
+
+ mPetCreateSpell.clear();
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 creature_id = fields[0].GetUInt32();
+
+ if(!creature_id || !sCreatureStorage.LookupEntry<CreatureInfo>(creature_id))
+ continue;
+
+ PetCreateSpellEntry PetCreateSpell;
+ for(int i = 0; i < 4; i++)
+ {
+ PetCreateSpell.spellid[i] = fields[i + 1].GetUInt32();
+
+ if(PetCreateSpell.spellid[i] && !sSpellStore.LookupEntry(PetCreateSpell.spellid[i]))
+ sLog.outErrorDb("Spell %u listed in `petcreateinfo_spell` does not exist",PetCreateSpell.spellid[i]);
+ }
+
+ mPetCreateSpell[creature_id] = PetCreateSpell;
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pet create spells", count );
+}
+
+void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
+{
+ if(sWorld.IsScriptScheduled()) // function don't must be called in time scripts use.
+ return;
+
+ sLog.outString( "%s :", tablename);
+
+ scripts.clear(); // need for reload support
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,dataint, x, y, z, o FROM %s", tablename );
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u script definitions", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+ ScriptInfo tmp;
+ tmp.id = fields[0].GetUInt32();
+ tmp.delay = fields[1].GetUInt32();
+ tmp.command = fields[2].GetUInt32();
+ tmp.datalong = fields[3].GetUInt32();
+ tmp.datalong2 = fields[4].GetUInt32();
+ tmp.dataint = fields[5].GetInt32();
+ tmp.x = fields[6].GetFloat();
+ tmp.y = fields[7].GetFloat();
+ tmp.z = fields[8].GetFloat();
+ tmp.o = fields[9].GetFloat();
+
+ // generic command args check
+ switch(tmp.command)
+ {
+ case SCRIPT_COMMAND_TALK:
+ {
+ if(tmp.datalong > 3)
+ {
+ sLog.outErrorDb("Table `%s` has invalid talk type (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+ if(tmp.dataint==0)
+ {
+ sLog.outErrorDb("Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,tmp.id);
+ continue;
+ }
+ if(tmp.dataint < MIN_DB_SCRIPT_STRING_ID || tmp.dataint >= MAX_DB_SCRIPT_STRING_ID)
+ {
+ sLog.outErrorDb("Table `%s` has out of range text id (dataint = %i expected %u-%u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID,tmp.id);
+ continue;
+ }
+
+ // if(!objmgr.GetMangosStringLocale(tmp.dataint)) will checked after db_script_string loading
+ break;
+ }
+
+ case SCRIPT_COMMAND_TELEPORT_TO:
+ {
+ if(!sMapStore.LookupEntry(tmp.datalong))
+ {
+ sLog.outErrorDb("Table `%s` has invalid map (Id: %u) in SCRIPT_COMMAND_TELEPORT_TO for script id %u",tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+
+ if(!Trinity::IsValidMapCoord(tmp.x,tmp.y,tmp.z,tmp.o))
+ {
+ sLog.outErrorDb("Table `%s` has invalid coordinates (X: %f Y: %f) in SCRIPT_COMMAND_TELEPORT_TO for script id %u",tablename,tmp.x,tmp.y,tmp.id);
+ continue;
+ }
+ break;
+ }
+
+ case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
+ {
+ if(!Trinity::IsValidMapCoord(tmp.x,tmp.y,tmp.z,tmp.o))
+ {
+ sLog.outErrorDb("Table `%s` has invalid coordinates (X: %f Y: %f) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u",tablename,tmp.x,tmp.y,tmp.id);
+ continue;
+ }
+
+ if(!GetCreatureTemplate(tmp.datalong))
+ {
+ sLog.outErrorDb("Table `%s` has invalid creature (Entry: %u) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u",tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+ break;
+ }
+
+ case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
+ {
+ GameObjectData const* data = GetGOData(tmp.datalong);
+ if(!data)
+ {
+ sLog.outErrorDb("Table `%s` has invalid gameobject (GUID: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+
+ GameObjectInfo const* info = GetGameObjectInfo(data->id);
+ if(!info)
+ {
+ sLog.outErrorDb("Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,tmp.datalong,data->id,tmp.id);
+ continue;
+ }
+
+ if( info->type==GAMEOBJECT_TYPE_FISHINGNODE ||
+ info->type==GAMEOBJECT_TYPE_FISHINGHOLE ||
+ info->type==GAMEOBJECT_TYPE_DOOR ||
+ info->type==GAMEOBJECT_TYPE_BUTTON ||
+ info->type==GAMEOBJECT_TYPE_TRAP )
+ {
+ sLog.outErrorDb("Table `%s` have gameobject type (%u) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u",tablename,info->id,tmp.id);
+ continue;
+ }
+ break;
+ }
+ case SCRIPT_COMMAND_OPEN_DOOR:
+ case SCRIPT_COMMAND_CLOSE_DOOR:
+ {
+ GameObjectData const* data = GetGOData(tmp.datalong);
+ if(!data)
+ {
+ sLog.outErrorDb("Table `%s` has invalid gameobject (GUID: %u) in %s for script id %u",tablename,tmp.datalong,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id);
+ continue;
+ }
+
+ GameObjectInfo const* info = GetGameObjectInfo(data->id);
+ if(!info)
+ {
+ sLog.outErrorDb("Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in %s for script id %u",tablename,tmp.datalong,data->id,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id);
+ continue;
+ }
+
+ if( info->type!=GAMEOBJECT_TYPE_DOOR)
+ {
+ sLog.outErrorDb("Table `%s` has gameobject type (%u) non supported by command %s for script id %u",tablename,info->id,(tmp.command==SCRIPT_COMMAND_OPEN_DOOR ? "SCRIPT_COMMAND_OPEN_DOOR" : "SCRIPT_COMMAND_CLOSE_DOOR"),tmp.id);
+ continue;
+ }
+
+ break;
+ }
+ case SCRIPT_COMMAND_QUEST_EXPLORED:
+ {
+ Quest const* quest = GetQuestTemplate(tmp.datalong);
+ if(!quest)
+ {
+ sLog.outErrorDb("Table `%s` has invalid quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+
+ if(!quest->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
+ {
+ sLog.outErrorDb("Table `%s` has quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT in quest flags. Script command or quest flags wrong. Quest modified to require objective.",tablename,tmp.datalong,tmp.id);
+
+ // this will prevent quest completing without objective
+ const_cast<Quest*>(quest)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
+
+ // continue; - quest objective requirement set and command can be allowed
+ }
+
+ if(float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE)
+ {
+ sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",
+ tablename,tmp.datalong2,tmp.id);
+ continue;
+ }
+
+ if(tmp.datalong2 && float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE)
+ {
+ sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, max distance is %f or 0 for disable distance check",
+ tablename,tmp.datalong2,tmp.id,DEFAULT_VISIBILITY_DISTANCE);
+ continue;
+ }
+
+ if(tmp.datalong2 && float(tmp.datalong2) < INTERACTION_DISTANCE)
+ {
+ sLog.outErrorDb("Table `%s` has too small distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, min distance is %f or 0 for disable distance check",
+ tablename,tmp.datalong2,tmp.id,INTERACTION_DISTANCE);
+ continue;
+ }
+
+ break;
+ }
+
+ case SCRIPT_COMMAND_REMOVE_AURA:
+ case SCRIPT_COMMAND_CAST_SPELL:
+ {
+ if(!sSpellStore.LookupEntry(tmp.datalong))
+ {
+ sLog.outErrorDb("Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_REMOVE_AURA or SCRIPT_COMMAND_CAST_SPELL for script id %u",
+ tablename,tmp.datalong,tmp.id);
+ continue;
+ }
+ break;
+ }
+ }
+
+ if (scripts.find(tmp.id) == scripts.end())
+ {
+ ScriptMap emptyMap;
+ scripts[tmp.id] = emptyMap;
+ }
+ scripts[tmp.id].insert(std::pair<uint32, ScriptInfo>(tmp.delay, tmp));
+
+ ++count;
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u script definitions", count );
+}
+
+void ObjectMgr::LoadGameObjectScripts()
+{
+ LoadScripts(sGameObjectScripts, "gameobject_scripts");
+
+ // check ids
+ for(ScriptMapMap::const_iterator itr = sGameObjectScripts.begin(); itr != sGameObjectScripts.end(); ++itr)
+ {
+ if(!GetGOData(itr->first))
+ sLog.outErrorDb("Table `gameobject_scripts` has not existing gameobject (GUID: %u) as script id",itr->first);
+ }
+}
+
+void ObjectMgr::LoadQuestEndScripts()
+{
+ LoadScripts(sQuestEndScripts, "quest_end_scripts");
+
+ // check ids
+ for(ScriptMapMap::const_iterator itr = sQuestEndScripts.begin(); itr != sQuestEndScripts.end(); ++itr)
+ {
+ if(!GetQuestTemplate(itr->first))
+ sLog.outErrorDb("Table `quest_end_scripts` has not existing quest (Id: %u) as script id",itr->first);
+ }
+}
+
+void ObjectMgr::LoadQuestStartScripts()
+{
+ LoadScripts(sQuestStartScripts,"quest_start_scripts");
+
+ // check ids
+ for(ScriptMapMap::const_iterator itr = sQuestStartScripts.begin(); itr != sQuestStartScripts.end(); ++itr)
+ {
+ if(!GetQuestTemplate(itr->first))
+ sLog.outErrorDb("Table `quest_start_scripts` has not existing quest (Id: %u) as script id",itr->first);
+ }
+}
+
+void ObjectMgr::LoadSpellScripts()
+{
+ LoadScripts(sSpellScripts, "spell_scripts");
+
+ // check ids
+ for(ScriptMapMap::const_iterator itr = sSpellScripts.begin(); itr != sSpellScripts.end(); ++itr)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first);
+
+ if(!spellInfo)
+ {
+ sLog.outErrorDb("Table `spell_scripts` has not existing spell (Id: %u) as script id",itr->first);
+ continue;
+ }
+
+ //check for correct spellEffect
+ bool found = false;
+ for(int i=0; i<3; ++i)
+ {
+ // skip empty effects
+ if( !spellInfo->Effect[i] )
+ continue;
+
+ if( spellInfo->Effect[i] == SPELL_EFFECT_SCRIPT_EFFECT )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found)
+ sLog.outErrorDb("Table `spell_scripts` has unsupported spell (Id: %u) without SPELL_EFFECT_SCRIPT_EFFECT (%u) spell effect",itr->first,SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+}
+
+void ObjectMgr::LoadEventScripts()
+{
+ LoadScripts(sEventScripts, "event_scripts");
+
+ std::set<uint32> evt_scripts;
+ // Load all possible script entries from gameobjects
+ for(uint32 i = 1; i < sGOStorage.MaxEntry; ++i)
+ {
+ GameObjectInfo const * goInfo = sGOStorage.LookupEntry<GameObjectInfo>(i);
+ if (goInfo)
+ {
+ switch(goInfo->type)
+ {
+ case GAMEOBJECT_TYPE_GOOBER:
+ if(goInfo->goober.eventId)
+ evt_scripts.insert(goInfo->goober.eventId);
+ break;
+ case GAMEOBJECT_TYPE_CHEST:
+ if(goInfo->chest.eventId)
+ evt_scripts.insert(goInfo->chest.eventId);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ // Load all possible script entries from spells
+ for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
+ {
+ SpellEntry const * spell = sSpellStore.LookupEntry(i);
+ if (spell)
+ {
+ for(int j=0; j<3; ++j)
+ {
+ if( spell->Effect[j] == SPELL_EFFECT_SEND_EVENT )
+ {
+ if (spell->EffectMiscValue[j])
+ evt_scripts.insert(spell->EffectMiscValue[j]);
+ }
+ }
+ }
+ }
+ // Then check if all scripts are in above list of possible script entries
+ for(ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr)
+ {
+ std::set<uint32>::const_iterator itr2 = evt_scripts.find(itr->first);
+ if (itr2 == evt_scripts.end())
+ sLog.outErrorDb("Table `event_scripts` has script (Id: %u) not referring to any gameobject_template type 10 data2 field or type 3 data6 field or any spell effect %u", itr->first, SPELL_EFFECT_SEND_EVENT);
+ }
+}
+
+void ObjectMgr::LoadItemTexts()
+{
+ QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text");
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u item pages", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ Field* fields;
+ do
+ {
+ bar.step();
+
+ fields = result->Fetch();
+
+ mItemTexts[ fields[0].GetUInt32() ] = fields[1].GetCppString();
+
+ ++count;
+
+ } while ( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u item texts", count );
+}
+
+void ObjectMgr::LoadPageTexts()
+{
+ sPageTextStore.Free(); // for reload case
+
+ sPageTextStore.Load();
+ sLog.outString( ">> Loaded %u page texts", sPageTextStore.RecordCount );
+ sLog.outString();
+
+ for(uint32 i = 1; i < sPageTextStore.MaxEntry; ++i)
+ {
+ // check data correctness
+ PageText const* page = sPageTextStore.LookupEntry<PageText>(i);
+ if(!page)
+ continue;
+
+ if(page->Next_Page && !sPageTextStore.LookupEntry<PageText>(page->Next_Page))
+ {
+ sLog.outErrorDb("Page text (Id: %u) has not existing next page (Id:%u)", i,page->Next_Page);
+ continue;
+ }
+
+ // detect circular reference
+ std::set<uint32> checkedPages;
+ for(PageText const* pageItr = page; pageItr; pageItr = sPageTextStore.LookupEntry<PageText>(pageItr->Next_Page))
+ {
+ if(!pageItr->Next_Page)
+ break;
+ checkedPages.insert(pageItr->Page_ID);
+ if(checkedPages.find(pageItr->Next_Page)!=checkedPages.end())
+ {
+ std::ostringstream ss;
+ ss<< "The text page(s) ";
+ for (std::set<uint32>::iterator itr= checkedPages.begin();itr!=checkedPages.end(); itr++)
+ ss << *itr << " ";
+ ss << "create(s) a circular reference, which can cause the server to freeze. Changing Next_Page of page "
+ << pageItr->Page_ID <<" to 0";
+ sLog.outErrorDb(ss.str().c_str());
+ const_cast<PageText*>(pageItr)->Next_Page = 0;
+ break;
+ }
+ }
+ }
+}
+
+void ObjectMgr::LoadPageTextLocales()
+{
+ mPageTextLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 PageText locale strings. DB table `locales_page_text` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ PageTextLocale& data = mPageTextLocaleMap[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[i].GetCppString();
+ if(str.empty())
+ continue;
+
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Text.size() <= idx)
+ data.Text.resize(idx+1);
+
+ data.Text[idx] = str;
+ }
+ }
+
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u PageText locale strings", mPageTextLocaleMap.size() );
+}
+
+struct SQLInstanceLoader : public SQLStorageLoaderBase<SQLInstanceLoader>
+{
+ template<class D>
+ void convert_from_str(uint32 field_pos, char *src, D &dst)
+ {
+ dst = D(objmgr.GetScriptId(src));
+ }
+};
+
+void ObjectMgr::LoadInstanceTemplate()
+{
+ SQLInstanceLoader loader;
+ loader.Load(sInstanceTemplate);
+
+ for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
+ {
+ InstanceTemplate* temp = (InstanceTemplate*)GetInstanceTemplate(i);
+ if(!temp) continue;
+ const MapEntry* entry = sMapStore.LookupEntry(temp->map);
+ if(!entry)
+ {
+ sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: bad mapid %d for template!", temp->map);
+ continue;
+ }
+ else if(!entry->HasResetTime())
+ continue;
+
+ if(temp->reset_delay == 0)
+ {
+ // use defaults from the DBC
+ if(entry->SupportsHeroicMode())
+ {
+ temp->reset_delay = entry->resetTimeHeroic / DAY;
+ }
+ else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
+ {
+ temp->reset_delay = entry->resetTimeRaid / DAY;
+ }
+ }
+
+ // the reset_delay must be at least one day
+ temp->reset_delay = std::max((uint32)1, (uint32)(temp->reset_delay * sWorld.getRate(RATE_INSTANCE_RESET_TIME)));
+ }
+
+ sLog.outString( ">> Loaded %u Instance Template definitions", sInstanceTemplate.RecordCount );
+ sLog.outString();
+}
+
+void ObjectMgr::AddGossipText(GossipText *pGText)
+{
+ ASSERT( pGText->Text_ID );
+ ASSERT( mGossipText.find(pGText->Text_ID) == mGossipText.end() );
+ mGossipText[pGText->Text_ID] = pGText;
+}
+
+GossipText *ObjectMgr::GetGossipText(uint32 Text_ID)
+{
+ GossipTextMap::const_iterator itr;
+ for (itr = mGossipText.begin(); itr != mGossipText.end(); itr++)
+ {
+ if(itr->second->Text_ID == Text_ID)
+ return itr->second;
+ }
+ return NULL;
+}
+
+void ObjectMgr::LoadGossipText()
+{
+ GossipText *pGText;
+ QueryResult *result = WorldDatabase.Query( "SELECT * FROM npc_text" );
+
+ int count = 0;
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u npc texts", count );
+ return;
+ }
+
+ int cic;
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ cic = 0;
+
+ Field *fields = result->Fetch();
+
+ bar.step();
+
+ pGText = new GossipText;
+ pGText->Text_ID = fields[cic++].GetUInt32();
+
+ for (int i=0; i< 8; i++)
+ {
+ pGText->Options[i].Text_0 = fields[cic++].GetCppString();
+ pGText->Options[i].Text_1 = fields[cic++].GetCppString();
+
+ pGText->Options[i].Language = fields[cic++].GetUInt32();
+ pGText->Options[i].Probability = fields[cic++].GetFloat();
+
+ pGText->Options[i].Emotes[0]._Delay = fields[cic++].GetUInt32();
+ pGText->Options[i].Emotes[0]._Emote = fields[cic++].GetUInt32();
+
+ pGText->Options[i].Emotes[1]._Delay = fields[cic++].GetUInt32();
+ pGText->Options[i].Emotes[1]._Emote = fields[cic++].GetUInt32();
+
+ pGText->Options[i].Emotes[2]._Delay = fields[cic++].GetUInt32();
+ pGText->Options[i].Emotes[2]._Emote = fields[cic++].GetUInt32();
+ }
+
+ if ( !pGText->Text_ID ) continue;
+ AddGossipText( pGText );
+
+ } while( result->NextRow() );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u npc texts", count );
+ delete result;
+}
+
+void ObjectMgr::LoadNpcTextLocales()
+{
+ mNpcTextLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,"
+ "Text0_0_loc1,Text0_1_loc1,Text1_0_loc1,Text1_1_loc1,Text2_0_loc1,Text2_1_loc1,Text3_0_loc1,Text3_1_loc1,Text4_0_loc1,Text4_1_loc1,Text5_0_loc1,Text5_1_loc1,Text6_0_loc1,Text6_1_loc1,Text7_0_loc1,Text7_1_loc1,"
+ "Text0_0_loc2,Text0_1_loc2,Text1_0_loc2,Text1_1_loc2,Text2_0_loc2,Text2_1_loc2,Text3_0_loc2,Text3_1_loc1,Text4_0_loc2,Text4_1_loc2,Text5_0_loc2,Text5_1_loc2,Text6_0_loc2,Text6_1_loc2,Text7_0_loc2,Text7_1_loc2,"
+ "Text0_0_loc3,Text0_1_loc3,Text1_0_loc3,Text1_1_loc3,Text2_0_loc3,Text2_1_loc3,Text3_0_loc3,Text3_1_loc1,Text4_0_loc3,Text4_1_loc3,Text5_0_loc3,Text5_1_loc3,Text6_0_loc3,Text6_1_loc3,Text7_0_loc3,Text7_1_loc3,"
+ "Text0_0_loc4,Text0_1_loc4,Text1_0_loc4,Text1_1_loc4,Text2_0_loc4,Text2_1_loc4,Text3_0_loc4,Text3_1_loc1,Text4_0_loc4,Text4_1_loc4,Text5_0_loc4,Text5_1_loc4,Text6_0_loc4,Text6_1_loc4,Text7_0_loc4,Text7_1_loc4,"
+ "Text0_0_loc5,Text0_1_loc5,Text1_0_loc5,Text1_1_loc5,Text2_0_loc5,Text2_1_loc5,Text3_0_loc5,Text3_1_loc1,Text4_0_loc5,Text4_1_loc5,Text5_0_loc5,Text5_1_loc5,Text6_0_loc5,Text6_1_loc5,Text7_0_loc5,Text7_1_loc5,"
+ "Text0_0_loc6,Text0_1_loc6,Text1_0_loc6,Text1_1_loc6,Text2_0_loc6,Text2_1_loc6,Text3_0_loc6,Text3_1_loc1,Text4_0_loc6,Text4_1_loc6,Text5_0_loc6,Text5_1_loc6,Text6_0_loc6,Text6_1_loc6,Text7_0_loc6,Text7_1_loc6,"
+ "Text0_0_loc7,Text0_1_loc7,Text1_0_loc7,Text1_1_loc7,Text2_0_loc7,Text2_1_loc7,Text3_0_loc7,Text3_1_loc1,Text4_0_loc7,Text4_1_loc7,Text5_0_loc7,Text5_1_loc7,Text6_0_loc7,Text6_1_loc7,Text7_0_loc7,Text7_1_loc7, "
+ "Text0_0_loc8,Text0_1_loc8,Text1_0_loc8,Text1_1_loc8,Text2_0_loc8,Text2_1_loc8,Text3_0_loc8,Text3_1_loc1,Text4_0_loc8,Text4_1_loc8,Text5_0_loc8,Text5_1_loc8,Text6_0_loc8,Text6_1_loc8,Text7_0_loc8,Text7_1_loc8 "
+ " FROM locales_npc_text");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 Quest locale strings. DB table `locales_npc_text` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ NpcTextLocale& data = mNpcTextLocaleMap[entry];
+
+ for(int i=1; i<MAX_LOCALE; ++i)
+ {
+ for(int j=0; j<8; ++j)
+ {
+ std::string str0 = fields[1+8*2*(i-1)+2*j].GetCppString();
+ if(!str0.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Text_0[j].size() <= idx)
+ data.Text_0[j].resize(idx+1);
+
+ data.Text_0[j][idx] = str0;
+ }
+ }
+ std::string str1 = fields[1+8*2*(i-1)+2*j+1].GetCppString();
+ if(!str1.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Text_1[j].size() <= idx)
+ data.Text_1[j].resize(idx+1);
+
+ data.Text_1[j][idx] = str1;
+ }
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u NpcText locale strings", mNpcTextLocaleMap.size() );
+}
+
+//not very fast function but it is called only once a day, or on starting-up
+void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
+{
+ time_t basetime = time(NULL);
+ sLog.outDebug("Returning mails current time: hour: %d, minute: %d, second: %d ", localtime(&basetime)->tm_hour, localtime(&basetime)->tm_min, localtime(&basetime)->tm_sec);
+ //delete all old mails without item and without body immediately, if starting server
+ if (!serverUp)
+ CharacterDatabase.PExecute("DELETE FROM mail WHERE expire_time < '" I64FMTD "' AND has_items = '0' AND itemTextId = 0", (uint64)basetime);
+ // 0 1 2 3 4 5 6 7 8 9
+ QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" I64FMTD "'", (uint64)basetime);
+ if ( !result )
+ return; // any mails need to be returned or deleted
+ Field *fields;
+ //std::ostringstream delitems, delmails; //will be here for optimization
+ //bool deletemail = false, deleteitem = false;
+ //delitems << "DELETE FROM item_instance WHERE guid IN ( ";
+ //delmails << "DELETE FROM mail WHERE id IN ( "
+ do
+ {
+ fields = result->Fetch();
+ Mail *m = new Mail;
+ m->messageID = fields[0].GetUInt32();
+ m->messageType = fields[1].GetUInt8();
+ m->sender = fields[2].GetUInt32();
+ m->receiver = fields[3].GetUInt32();
+ m->itemTextId = fields[4].GetUInt32();
+ bool has_items = fields[5].GetBool();
+ m->expire_time = (time_t)fields[6].GetUInt64();
+ m->deliver_time = 0;
+ m->COD = fields[7].GetUInt32();
+ m->checked = fields[8].GetUInt32();
+ m->mailTemplateId = fields[9].GetInt16();
+
+ Player *pl = 0;
+ if (serverUp)
+ pl = GetPlayer((uint64)m->receiver);
+ if (pl && pl->m_mailsLoaded)
+ { //this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail
+ //his in mailbox and he has already listed his mails )
+ delete m;
+ continue;
+ }
+ //delete or return mail:
+ if (has_items)
+ {
+ QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", m->messageID);
+ if(resultItems)
+ {
+ do
+ {
+ Field *fields2 = resultItems->Fetch();
+
+ uint32 item_guid_low = fields2[0].GetUInt32();
+ uint32 item_template = fields2[1].GetUInt32();
+
+ m->AddItem(item_guid_low, item_template);
+ }
+ while (resultItems->NextRow());
+
+ delete resultItems;
+ }
+ //if it is mail from AH, it shouldn't be returned, but deleted
+ if (m->messageType != MAIL_NORMAL || (m->checked & (MAIL_CHECK_MASK_AUCTION | MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED)))
+ {
+ // mail open and then not returned
+ for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
+ CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
+ }
+ else
+ {
+ //mail will be returned:
+ CharacterDatabase.PExecute("UPDATE mail SET sender = '%u', receiver = '%u', expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',cod = '0', checked = '%u' WHERE id = '%u'", m->receiver, m->sender, (uint64)(basetime + 30*DAY), (uint64)basetime, MAIL_CHECK_MASK_RETURNED, m->messageID);
+ delete m;
+ continue;
+ }
+ }
+
+ if (m->itemTextId)
+ CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId);
+
+ //deletemail = true;
+ //delmails << m->messageID << ", ";
+ CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
+ delete m;
+ } while (result->NextRow());
+ delete result;
+}
+
+void ObjectMgr::LoadQuestAreaTriggers()
+{
+ mQuestAreaTriggerMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query( "SELECT id,quest FROM areatrigger_involvedrelation" );
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u quest trigger points", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 trigger_ID = fields[0].GetUInt32();
+ uint32 quest_ID = fields[1].GetUInt32();
+
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(trigger_ID);
+ if(!atEntry)
+ {
+ sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",trigger_ID);
+ continue;
+ }
+
+ Quest const* quest = GetQuestTemplate(quest_ID);
+
+ if(!quest)
+ {
+ sLog.outErrorDb("Table `areatrigger_involvedrelation` has record (id: %u) for not existing quest %u",trigger_ID,quest_ID);
+ continue;
+ }
+
+ if(!quest->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
+ {
+ sLog.outErrorDb("Table `areatrigger_involvedrelation` has record (id: %u) for not quest %u, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Trigger or quest flags must be fixed, quest modified to require objective.",trigger_ID,quest_ID);
+
+ // this will prevent quest completing without objective
+ const_cast<Quest*>(quest)->SetFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT);
+
+ // continue; - quest modified to required objective and trigger can be allowed.
+ }
+
+ mQuestAreaTriggerMap[trigger_ID] = quest_ID;
+
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u quest trigger points", count );
+}
+
+void ObjectMgr::LoadTavernAreaTriggers()
+{
+ mTavernAreaTriggerSet.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT id FROM areatrigger_tavern");
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u tavern triggers", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 Trigger_ID = fields[0].GetUInt32();
+
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
+ if(!atEntry)
+ {
+ sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
+ continue;
+ }
+
+ mTavernAreaTriggerSet.insert(Trigger_ID);
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u tavern triggers", count );
+}
+
+void ObjectMgr::LoadAreaTriggerScripts()
+{
+ mAreaTriggerScripts.clear(); // need for reload case
+ QueryResult *result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u areatrigger scripts", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 Trigger_ID = fields[0].GetUInt32();
+ const char *scriptName = fields[1].GetString();
+
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
+ if(!atEntry)
+ {
+ sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
+ continue;
+ }
+ mAreaTriggerScripts[Trigger_ID] = GetScriptId(scriptName);
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u areatrigger scripts", count );
+}
+
+uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid )
+{
+ bool found = false;
+ float dist;
+ uint32 id = 0;
+
+ for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
+ {
+ TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
+ if(node && node->map_id == mapid)
+ {
+ float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
+ if(found)
+ {
+ if(dist2 < dist)
+ {
+ dist = dist2;
+ id = i;
+ }
+ }
+ else
+ {
+ found = true;
+ dist = dist2;
+ id = i;
+ }
+ }
+ }
+
+ return id;
+}
+
+void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost)
+{
+ TaxiPathSetBySource::iterator src_i = sTaxiPathSetBySource.find(source);
+ if(src_i==sTaxiPathSetBySource.end())
+ {
+ path = 0;
+ cost = 0;
+ return;
+ }
+
+ TaxiPathSetForSource& pathSet = src_i->second;
+
+ TaxiPathSetForSource::iterator dest_i = pathSet.find(destination);
+ if(dest_i==pathSet.end())
+ {
+ path = 0;
+ cost = 0;
+ return;
+ }
+
+ cost = dest_i->second.price;
+ path = dest_i->second.ID;
+}
+
+uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )
+{
+ uint16 mount_entry = 0;
+ uint16 mount_id = 0;
+
+ TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
+ if(node)
+ {
+ if (team == ALLIANCE) mount_entry = node->alliance_mount_type;
+ else mount_entry = node->horde_mount_type;
+
+ CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry);
+ if (cinfo)
+ {
+ if(! (mount_id = cinfo->GetRandomValidModelId()))
+ {
+ sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry);
+ return false;
+ }
+ }
+ }
+
+ CreatureModelInfo const *minfo = GetCreatureModelInfo(mount_id);
+ if(!minfo)
+ {
+ sLog.outErrorDb("Taxi mount (Entry: %u) for taxi node (Id: %u) for team %u has model %u not found in table `creature_model_info`, can't load. ",
+ mount_entry,id,team,mount_id);
+
+ return false;
+ }
+ if(minfo->modelid_other_gender!=0)
+ mount_id = urand(0,1) ? mount_id : minfo->modelid_other_gender;
+
+ return mount_id;
+}
+
+void ObjectMgr::GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds)
+{
+ if(path >= sTaxiPathNodesByPath.size())
+ return;
+
+ TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path];
+
+ pathnodes.Resize(nodeList.size());
+ mapIds.resize(nodeList.size());
+
+ for(size_t i = 0; i < nodeList.size(); ++i)
+ {
+ pathnodes[ i ].x = nodeList[i].x;
+ pathnodes[ i ].y = nodeList[i].y;
+ pathnodes[ i ].z = nodeList[i].z;
+
+ mapIds[i] = nodeList[i].mapid;
+ }
+}
+
+void ObjectMgr::GetTransportPathNodes( uint32 path, TransportPath &pathnodes )
+{
+ if(path >= sTaxiPathNodesByPath.size())
+ return;
+
+ TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path];
+
+ pathnodes.Resize(nodeList.size());
+
+ for(size_t i = 0; i < nodeList.size(); ++i)
+ {
+ pathnodes[ i ].mapid = nodeList[i].mapid;
+ pathnodes[ i ].x = nodeList[i].x;
+ pathnodes[ i ].y = nodeList[i].y;
+ pathnodes[ i ].z = nodeList[i].z;
+ pathnodes[ i ].actionFlag = nodeList[i].actionFlag;
+ pathnodes[ i ].delay = nodeList[i].delay;
+ }
+}
+
+void ObjectMgr::LoadGraveyardZones()
+{
+ mGraveYardMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT id,ghost_zone,faction FROM game_graveyard_zone");
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u graveyard-zone links", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 safeLocId = fields[0].GetUInt32();
+ uint32 zoneId = fields[1].GetUInt32();
+ uint32 team = fields[2].GetUInt32();
+
+ WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(safeLocId);
+ if(!entry)
+ {
+ sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped.",safeLocId);
+ continue;
+ }
+
+ AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId);
+ if(!areaEntry)
+ {
+ sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing zone id (%u), skipped.",zoneId);
+ continue;
+ }
+
+ if(areaEntry->zone != 0)
+ {
+ sLog.outErrorDb("Table `game_graveyard_zone` has record subzone id (%u) instead of zone, skipped.",zoneId);
+ continue;
+ }
+
+ if(team!=0 && team!=HORDE && team!=ALLIANCE)
+ {
+ sLog.outErrorDb("Table `game_graveyard_zone` has record for non player faction (%u), skipped.",team);
+ continue;
+ }
+
+ if(!AddGraveYardLink(safeLocId,zoneId,team,false))
+ sLog.outErrorDb("Table `game_graveyard_zone` has a duplicate record for Graveyard (ID: %u) and Zone (ID: %u), skipped.",safeLocId,zoneId);
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u graveyard-zone links", count );
+}
+
+WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team)
+{
+ // search for zone associated closest graveyard
+ uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y);
+
+ // Simulate std. algorithm:
+ // found some graveyard associated to (ghost_zone,ghost_map)
+ //
+ // if mapId == graveyard.mapId (ghost in plain zone or city or battleground) and search graveyard at same map
+ // then check faction
+ // if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated
+ // then check faction
+ GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId);
+ GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId);
+ if(graveLow==graveUp)
+ {
+ sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team);
+ return NULL;
+ }
+
+ // at corpse map
+ bool foundNear = false;
+ float distNear;
+ WorldSafeLocsEntry const* entryNear = NULL;
+
+ // at entrance map for corpse map
+ bool foundEntr = false;
+ float distEntr;
+ WorldSafeLocsEntry const* entryEntr = NULL;
+
+ // some where other
+ WorldSafeLocsEntry const* entryFar = NULL;
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(MapId);
+
+ for(GraveYardMap::const_iterator itr = graveLow; itr != graveUp; ++itr)
+ {
+ GraveYardData const& data = itr->second;
+
+ WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(data.safeLocId);
+ if(!entry)
+ {
+ sLog.outErrorDb("Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped.",data.safeLocId);
+ continue;
+ }
+
+ // skip enemy faction graveyard
+ // team == 0 case can be at call from .neargrave
+ if(data.team != 0 && team != 0 && data.team != team)
+ continue;
+
+ // find now nearest graveyard at other map
+ if(MapId != entry->map_id)
+ {
+ // if find graveyard at different map from where entrance placed (or no entrance data), use any first
+ if (!mapEntry || mapEntry->entrance_map < 0 || mapEntry->entrance_map != entry->map_id ||
+ mapEntry->entrance_x == 0 && mapEntry->entrance_y == 0)
+ {
+ // not have any corrdinates for check distance anyway
+ entryFar = entry;
+ continue;
+ }
+
+ // at entrance map calculate distance (2D);
+ float dist2 = (entry->x - mapEntry->entrance_x)*(entry->x - mapEntry->entrance_x)
+ +(entry->y - mapEntry->entrance_y)*(entry->y - mapEntry->entrance_y);
+ if(foundEntr)
+ {
+ if(dist2 < distEntr)
+ {
+ distEntr = dist2;
+ entryEntr = entry;
+ }
+ }
+ else
+ {
+ foundEntr = true;
+ distEntr = dist2;
+ entryEntr = entry;
+ }
+ }
+ // find now nearest graveyard at same map
+ else
+ {
+ float dist2 = (entry->x - x)*(entry->x - x)+(entry->y - y)*(entry->y - y)+(entry->z - z)*(entry->z - z);
+ if(foundNear)
+ {
+ if(dist2 < distNear)
+ {
+ distNear = dist2;
+ entryNear = entry;
+ }
+ }
+ else
+ {
+ foundNear = true;
+ distNear = dist2;
+ entryNear = entry;
+ }
+ }
+ }
+
+ if(entryNear)
+ return entryNear;
+
+ if(entryEntr)
+ return entryEntr;
+
+ return entryFar;
+}
+
+GraveYardData const* ObjectMgr::FindGraveYardData(uint32 id, uint32 zoneId)
+{
+ GraveYardMap::const_iterator graveLow = mGraveYardMap.lower_bound(zoneId);
+ GraveYardMap::const_iterator graveUp = mGraveYardMap.upper_bound(zoneId);
+
+ for(GraveYardMap::const_iterator itr = graveLow; itr != graveUp; ++itr)
+ {
+ if(itr->second.safeLocId==id)
+ return &itr->second;
+ }
+
+ return NULL;
+}
+
+bool ObjectMgr::AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inDB)
+{
+ if(FindGraveYardData(id,zoneId))
+ return false;
+
+ // add link to loaded data
+ GraveYardData data;
+ data.safeLocId = id;
+ data.team = team;
+
+ mGraveYardMap.insert(GraveYardMap::value_type(zoneId,data));
+
+ // add link to DB
+ if(inDB)
+ {
+ WorldDatabase.PExecuteLog("INSERT INTO game_graveyard_zone ( id,ghost_zone,faction) "
+ "VALUES ('%u', '%u','%u')",id,zoneId,team);
+ }
+
+ return true;
+}
+
+void ObjectMgr::RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inDB)
+{
+ GraveYardMap::iterator graveLow = mGraveYardMap.lower_bound(zoneId);
+ GraveYardMap::iterator graveUp = mGraveYardMap.upper_bound(zoneId);
+ if(graveLow==graveUp)
+ {
+ //sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team);
+ return;
+ }
+
+ bool found = false;
+
+ GraveYardMap::iterator itr;
+
+ for(itr = graveLow; itr != graveUp; ++itr)
+ {
+ GraveYardData & data = itr->second;
+
+ // skip not matching safezone id
+ if(data.safeLocId != id)
+ continue;
+
+ // skip enemy faction graveyard at same map (normal area, city, or battleground)
+ // team == 0 case can be at call from .neargrave
+ if(data.team != 0 && team != 0 && data.team != team)
+ continue;
+
+ found = true;
+ break;
+ }
+
+ // no match, return
+ if(!found)
+ return;
+
+ // remove from links
+ mGraveYardMap.erase(itr);
+
+ // remove link from DB
+ if(inDB)
+ {
+ WorldDatabase.PExecute("DELETE FROM game_graveyard_zone WHERE id = '%u' AND ghost_zone = '%u' AND faction = '%u'",id,zoneId,team);
+ }
+
+ return;
+}
+
+
+void ObjectMgr::LoadAreaTriggerTeleports()
+{
+ mAreaTriggers.clear(); // need for reload case
+
+ uint32 count = 0;
+
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12
+ QueryResult *result = WorldDatabase.Query("SELECT id, required_level, required_item, required_item2, heroic_key, heroic_key2, required_quest_done, required_failed_text, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport");
+ if( !result )
+ {
+
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u area trigger teleport definitions", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ bar.step();
+
+ ++count;
+
+ uint32 Trigger_ID = fields[0].GetUInt32();
+
+ AreaTrigger at;
+
+ at.requiredLevel = fields[1].GetUInt8();
+ at.requiredItem = fields[2].GetUInt32();
+ at.requiredItem2 = fields[3].GetUInt32();
+ at.heroicKey = fields[4].GetUInt32();
+ at.heroicKey2 = fields[5].GetUInt32();
+ at.requiredQuest = fields[6].GetUInt32();
+ at.requiredFailedText = fields[7].GetCppString();
+ at.target_mapId = fields[8].GetUInt32();
+ at.target_X = fields[9].GetFloat();
+ at.target_Y = fields[10].GetFloat();
+ at.target_Z = fields[11].GetFloat();
+ at.target_Orientation = fields[12].GetFloat();
+
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
+ if(!atEntry)
+ {
+ sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID);
+ continue;
+ }
+
+ if(at.requiredItem)
+ {
+ ItemPrototype const *pProto = GetItemPrototype(at.requiredItem);
+ if(!pProto)
+ {
+ sLog.outError("Key item %u does not exist for trigger %u, removing key requirement.", at.requiredItem, Trigger_ID);
+ at.requiredItem = 0;
+ }
+ }
+ if(at.requiredItem2)
+ {
+ ItemPrototype const *pProto = GetItemPrototype(at.requiredItem2);
+ if(!pProto)
+ {
+ sLog.outError("Second item %u not exist for trigger %u, remove key requirement.", at.requiredItem2, Trigger_ID);
+ at.requiredItem2 = 0;
+ }
+ }
+
+ if(at.heroicKey)
+ {
+ ItemPrototype const *pProto = GetItemPrototype(at.heroicKey);
+ if(!pProto)
+ {
+ sLog.outError("Heroic key item %u not exist for trigger %u, remove key requirement.", at.heroicKey, Trigger_ID);
+ at.heroicKey = 0;
+ }
+ }
+
+ if(at.heroicKey2)
+ {
+ ItemPrototype const *pProto = GetItemPrototype(at.heroicKey2);
+ if(!pProto)
+ {
+ sLog.outError("Heroic second key item %u not exist for trigger %u, remove key requirement.", at.heroicKey2, Trigger_ID);
+ at.heroicKey2 = 0;
+ }
+ }
+
+ if(at.requiredQuest)
+ {
+ if(!mQuestTemplates[at.requiredQuest])
+ {
+ sLog.outErrorDb("Required Quest %u not exist for trigger %u, remove quest done requirement.",at.requiredQuest,Trigger_ID);
+ at.requiredQuest = 0;
+ }
+ }
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
+ if(!mapEntry)
+ {
+ sLog.outErrorDb("Area trigger (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.",Trigger_ID,at.target_mapId);
+ continue;
+ }
+
+ if(at.target_X==0 && at.target_Y==0 && at.target_Z==0)
+ {
+ sLog.outErrorDb("Area trigger (ID:%u) target coordinates not provided.",Trigger_ID);
+ continue;
+ }
+
+ mAreaTriggers[Trigger_ID] = at;
+
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u area trigger teleport definitions", count );
+}
+
+AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
+{
+ const MapEntry *mapEntry = sMapStore.LookupEntry(Map);
+ if(!mapEntry) return NULL;
+ for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); itr++)
+ {
+ if(itr->second.target_mapId == mapEntry->entrance_map)
+ {
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
+ if(atEntry && atEntry->mapid == Map)
+ return &itr->second;
+ }
+ }
+ return NULL;
+}
+
+void ObjectMgr::SetHighestGuids()
+{
+ QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" );
+ if( result )
+ {
+ m_hiCharGuid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" );
+ if( result )
+ {
+ m_hiCreatureGuid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ // pet guids are not saved to DB, set to 0 (pet guid != pet id)
+ m_hiPetGuid = 0;
+
+ result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );
+ if( result )
+ {
+ m_hiItemGuid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ // Cleanup other tables from not existed guids (>=m_hiItemGuid)
+ CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_hiItemGuid);
+ CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_hiItemGuid);
+ CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_hiItemGuid);
+ CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_hiItemGuid);
+
+ result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" );
+ if( result )
+ {
+ m_hiGoGuid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" );
+ if( result )
+ {
+ m_auctionid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" );
+ if( result )
+ {
+ m_mailid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" );
+ if( result )
+ {
+ m_ItemTextId = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" );
+ if( result )
+ {
+ m_hiCorpseGuid = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
+ if (result)
+ {
+ m_arenaTeamId = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+
+ result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" );
+ if (result)
+ {
+ m_guildId = (*result)[0].GetUInt32()+1;
+ delete result;
+ }
+}
+
+uint32 ObjectMgr::GenerateArenaTeamId()
+{
+ if(m_arenaTeamId>=0xFFFFFFFE)
+ {
+ sLog.outError("Arena team ids overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_arenaTeamId++;
+}
+
+uint32 ObjectMgr::GenerateGuildId()
+{
+ if(m_guildId>=0xFFFFFFFE)
+ {
+ sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_guildId++;
+}
+
+uint32 ObjectMgr::GenerateAuctionID()
+{
+ if(m_auctionid>=0xFFFFFFFE)
+ {
+ sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_auctionid++;
+}
+
+uint32 ObjectMgr::GenerateMailID()
+{
+ if(m_mailid>=0xFFFFFFFE)
+ {
+ sLog.outError("Mail ids overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_mailid++;
+}
+
+uint32 ObjectMgr::GenerateItemTextID()
+{
+ if(m_ItemTextId>=0xFFFFFFFE)
+ {
+ sLog.outError("Item text ids overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_ItemTextId++;
+}
+
+uint32 ObjectMgr::CreateItemText(std::string text)
+{
+ uint32 newItemTextId = GenerateItemTextID();
+ //insert new itempage to container
+ mItemTexts[ newItemTextId ] = text;
+ //save new itempage
+ CharacterDatabase.escape_string(text);
+ //any Delete query needed, itemTextId is maximum of all ids
+ std::ostringstream query;
+ query << "INSERT INTO item_text (id,text) VALUES ( '" << newItemTextId << "', '" << text << "')";
+ CharacterDatabase.Execute(query.str().c_str()); //needs to be run this way, because mail body may be more than 1024 characters
+ return newItemTextId;
+}
+
+uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
+{
+ switch(guidhigh)
+ {
+ case HIGHGUID_ITEM:
+ if(m_hiItemGuid>=0xFFFFFFFE)
+ {
+ sLog.outError("Item guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiItemGuid++;
+ case HIGHGUID_UNIT:
+ if(m_hiCreatureGuid>=0x00FFFFFE)
+ {
+ sLog.outError("Creature guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiCreatureGuid++;
+ case HIGHGUID_PET:
+ if(m_hiPetGuid>=0x00FFFFFE)
+ {
+ sLog.outError("Pet guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiPetGuid++;
+ case HIGHGUID_PLAYER:
+ if(m_hiCharGuid>=0xFFFFFFFE)
+ {
+ sLog.outError("Players guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiCharGuid++;
+ case HIGHGUID_GAMEOBJECT:
+ if(m_hiGoGuid>=0x00FFFFFE)
+ {
+ sLog.outError("Gameobject guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiGoGuid++;
+ case HIGHGUID_CORPSE:
+ if(m_hiCorpseGuid>=0xFFFFFFFE)
+ {
+ sLog.outError("Corpse guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiCorpseGuid++;
+ case HIGHGUID_DYNAMICOBJECT:
+ if(m_hiDoGuid>=0xFFFFFFFE)
+ {
+ sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiDoGuid++;
+ default:
+ ASSERT(0);
+ }
+
+ ASSERT(0);
+ return 0;
+}
+
+void ObjectMgr::LoadGameObjectLocales()
+{
+ mGameObjectLocaleMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,"
+ "name_loc1,name_loc2,name_loc3,name_loc4,name_loc5,name_loc6,name_loc7,name_loc8,"
+ "castbarcaption_loc1,castbarcaption_loc2,castbarcaption_loc3,castbarcaption_loc4,"
+ "castbarcaption_loc5,castbarcaption_loc6,castbarcaption_loc7,castbarcaption_loc8 FROM locales_gameobject");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 gameobject locale strings. DB table `locales_gameobject` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ GameObjectLocale& data = mGameObjectLocaleMap[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[i].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.Name.size() <= idx)
+ data.Name.resize(idx+1);
+
+ data.Name[idx] = str;
+ }
+ }
+ }
+
+ for(int i = MAX_LOCALE; i < MAX_LOCALE*2-1; ++i)
+ {
+ std::string str = fields[i].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.CastBarCaption.size() <= idx)
+ data.CastBarCaption.resize(idx+1);
+
+ data.CastBarCaption[idx] = str;
+ }
+ }
+ }
+
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u gameobject locale strings", mGameObjectLocaleMap.size() );
+}
+
+struct SQLGameObjectLoader : public SQLStorageLoaderBase<SQLGameObjectLoader>
+{
+ template<class D>
+ void convert_from_str(uint32 field_pos, char *src, D &dst)
+ {
+ dst = D(objmgr.GetScriptId(src));
+ }
+};
+
+void ObjectMgr::LoadGameobjectInfo()
+{
+ SQLGameObjectLoader loader;
+ loader.Load(sGOStorage);
+
+ // some checks
+ for(uint32 id = 1; id < sGOStorage.MaxEntry; id++)
+ {
+ GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(id);
+ if(!goInfo)
+ continue;
+
+ switch(goInfo->type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: //0
+ {
+ if(goInfo->door.lockId)
+ {
+ if(!sLockStore.LookupEntry(goInfo->door.lockId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but lock (Id: %u) not found.",
+ id,goInfo->type,goInfo->door.lockId,goInfo->door.lockId);
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_BUTTON: //1
+ {
+ if(goInfo->button.lockId)
+ {
+ if(!sLockStore.LookupEntry(goInfo->button.lockId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but lock (Id: %u) not found.",
+ id,goInfo->type,goInfo->button.lockId,goInfo->button.lockId);
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_CHEST: //3
+ {
+ if(goInfo->chest.lockId)
+ {
+ if(!sLockStore.LookupEntry(goInfo->chest.lockId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but lock (Id: %u) not found.",
+ id,goInfo->type,goInfo->chest.lockId,goInfo->chest.lockId);
+ }
+ if(goInfo->chest.linkedTrapId) // linked trap
+ {
+ if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(goInfo->chest.linkedTrapId))
+ {
+ if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
+ id,goInfo->type,goInfo->chest.linkedTrapId,goInfo->chest.linkedTrapId,GAMEOBJECT_TYPE_TRAP);
+ }
+ /* disable check for while
+ else
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
+ id,goInfo->type,goInfo->chest.linkedTrapId,goInfo->chest.linkedTrapId);
+ */
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_TRAP: //6
+ {
+ /* disable check for while
+ if(goInfo->trap.spellId) // spell
+ {
+ if(!sSpellStore.LookupEntry(goInfo->trap.spellId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data3=%u but Spell (Entry %u) not exist.",
+ id,goInfo->type,goInfo->trap.spellId,goInfo->trap.spellId);
+ }
+ */
+ break;
+ }
+ case GAMEOBJECT_TYPE_CHAIR: //7
+ if(goInfo->chair.height > 2)
+ {
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but correct chair height in range 0..2.",
+ id,goInfo->type,goInfo->chair.height);
+
+ // prevent client and server unexpected work
+ const_cast<GameObjectInfo*>(goInfo)->chair.height = 0;
+ }
+ break;
+ case GAMEOBJECT_TYPE_SPELL_FOCUS: //8
+ {
+ if(goInfo->spellFocus.focusId)
+ {
+ if(!sSpellFocusObjectStore.LookupEntry(goInfo->spellFocus.focusId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but SpellFocus (Id: %u) not exist.",
+ id,goInfo->type,goInfo->spellFocus.focusId,goInfo->spellFocus.focusId);
+ }
+
+ if(goInfo->spellFocus.linkedTrapId) // linked trap
+ {
+ if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(goInfo->spellFocus.linkedTrapId))
+ {
+ if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
+ id,goInfo->type,goInfo->spellFocus.linkedTrapId,goInfo->spellFocus.linkedTrapId,GAMEOBJECT_TYPE_TRAP);
+ }
+ /* disable check for while
+ else
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
+ id,goInfo->type,goInfo->spellFocus.linkedTrapId,goInfo->spellFocus.linkedTrapId);
+ */
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_GOOBER: //10
+ {
+ if(goInfo->goober.pageId) // pageId
+ {
+ if(!sPageTextStore.LookupEntry<PageText>(goInfo->goober.pageId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but PageText (Entry %u) not exist.",
+ id,goInfo->type,goInfo->goober.pageId,goInfo->goober.pageId);
+ }
+ /* disable check for while
+ if(goInfo->goober.spellId) // spell
+ {
+ if(!sSpellStore.LookupEntry(goInfo->goober.spellId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data2=%u but Spell (Entry %u) not exist.",
+ id,goInfo->type,goInfo->goober.spellId,goInfo->goober.spellId);
+ }
+ */
+ if(goInfo->goober.linkedTrapId) // linked trap
+ {
+ if(GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(goInfo->goober.linkedTrapId))
+ {
+ if(trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data12=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type.",
+ id,goInfo->type,goInfo->goober.linkedTrapId,goInfo->goober.linkedTrapId,GAMEOBJECT_TYPE_TRAP);
+ }
+ /* disable check for while
+ else
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data12=%u but trap GO (Entry %u) not exist in `gameobject_template`.",
+ id,goInfo->type,goInfo->goober.linkedTrapId,goInfo->goober.linkedTrapId);
+ */
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_MO_TRANSPORT: //15
+ {
+ if(goInfo->moTransport.taxiPathId)
+ {
+ if(goInfo->moTransport.taxiPathId >= sTaxiPathNodesByPath.size() || sTaxiPathNodesByPath[goInfo->moTransport.taxiPathId].empty())
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data0=%u but TaxiPath (Id: %u) not exist.",
+ id,goInfo->type,goInfo->moTransport.taxiPathId,goInfo->moTransport.taxiPathId);
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18
+ {
+ /* disabled
+ if(goInfo->summoningRitual.spellId)
+ {
+ if(!sSpellStore.LookupEntry(goInfo->summoningRitual.spellId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but Spell (Entry %u) not exist.",
+ id,goInfo->type,goInfo->summoningRitual.spellId,goInfo->summoningRitual.spellId);
+ }
+ */
+ break;
+ }
+ case GAMEOBJECT_TYPE_SPELLCASTER: //22
+ {
+ if(goInfo->spellcaster.spellId) // spell
+ {
+ if(!sSpellStore.LookupEntry(goInfo->spellcaster.spellId))
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data3=%u but Spell (Entry %u) not exist.",
+ id,goInfo->type,goInfo->spellcaster.spellId,goInfo->spellcaster.spellId);
+ }
+ break;
+ }
+ }
+ }
+
+ sLog.outString( ">> Loaded %u game object templates", sGOStorage.RecordCount );
+ sLog.outString();
+}
+
+void ObjectMgr::LoadExplorationBaseXP()
+{
+ uint32 count = 0;
+ QueryResult *result = WorldDatabase.Query("SELECT level,basexp FROM exploration_basexp");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u BaseXP definitions", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+ uint32 level = fields[0].GetUInt32();
+ uint32 basexp = fields[1].GetUInt32();
+ mBaseXPTable[level] = basexp;
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u BaseXP definitions", count );
+}
+
+uint32 ObjectMgr::GetBaseXP(uint32 level)
+{
+ return mBaseXPTable[level] ? mBaseXPTable[level] : 0;
+}
+
+void ObjectMgr::LoadPetNames()
+{
+ uint32 count = 0;
+ QueryResult *result = WorldDatabase.Query("SELECT word,entry,half FROM pet_name_generation");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pet name parts", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+ std::string word = fields[0].GetString();
+ uint32 entry = fields[1].GetUInt32();
+ bool half = fields[2].GetBool();
+ if(half)
+ PetHalfName1[entry].push_back(word);
+ else
+ PetHalfName0[entry].push_back(word);
+ ++count;
+ }
+ while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pet name parts", count );
+}
+
+void ObjectMgr::LoadPetNumber()
+{
+ QueryResult* result = CharacterDatabase.Query("SELECT MAX(id) FROM character_pet");
+ if(result)
+ {
+ Field *fields = result->Fetch();
+ m_hiPetNumber = fields[0].GetUInt32()+1;
+ delete result;
+ }
+
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded the max pet number: %d", m_hiPetNumber-1);
+}
+
+std::string ObjectMgr::GeneratePetName(uint32 entry)
+{
+ std::vector<std::string> & list0 = PetHalfName0[entry];
+ std::vector<std::string> & list1 = PetHalfName1[entry];
+
+ if(list0.empty() || list1.empty())
+ {
+ CreatureInfo const *cinfo = GetCreatureTemplate(entry);
+ char* petname = GetPetName(cinfo->family, sWorld.GetDefaultDbcLocale());
+ if(!petname)
+ petname = cinfo->Name;
+ return std::string(petname);
+ }
+
+ return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1));
+}
+
+uint32 ObjectMgr::GeneratePetNumber()
+{
+ return ++m_hiPetNumber;
+}
+
+void ObjectMgr::LoadCorpses()
+{
+ uint32 count = 0;
+ // 0 1 2 3 4 5 6 7 8 10
+ QueryResult *result = CharacterDatabase.Query("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u corpses", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 guid = fields[result->GetFieldCount()-1].GetUInt32();
+
+ Corpse *corpse = new Corpse;
+ if(!corpse->LoadFromDB(guid,fields))
+ {
+ delete corpse;
+ continue;
+ }
+
+ ObjectAccessor::Instance().AddCorpse(corpse);
+
+ ++count;
+ }
+ while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u corpses", count );
+}
+
+void ObjectMgr::LoadReputationOnKill()
+{
+ uint32 count = 0;
+
+ // 0 1 2
+ QueryResult *result = WorldDatabase.Query("SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2,"
+ // 3 4 5 6 7 8 9
+ "IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
+ "FROM creature_onkill_reputation");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 creature_id = fields[0].GetUInt32();
+
+ ReputationOnKillEntry repOnKill;
+ repOnKill.repfaction1 = fields[1].GetUInt32();
+ repOnKill.repfaction2 = fields[2].GetUInt32();
+ repOnKill.is_teamaward1 = fields[3].GetBool();
+ repOnKill.reputation_max_cap1 = fields[4].GetUInt32();
+ repOnKill.repvalue1 = fields[5].GetInt32();
+ repOnKill.is_teamaward2 = fields[6].GetBool();
+ repOnKill.reputation_max_cap2 = fields[7].GetUInt32();
+ repOnKill.repvalue2 = fields[8].GetInt32();
+ repOnKill.team_dependent = fields[9].GetUInt8();
+
+ if(!GetCreatureTemplate(creature_id))
+ {
+ sLog.outErrorDb("Table `creature_onkill_reputation` have data for not existed creature entry (%u), skipped",creature_id);
+ continue;
+ }
+
+ if(repOnKill.repfaction1)
+ {
+ FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(repOnKill.repfaction1);
+ if(!factionEntry1)
+ {
+ sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction1);
+ continue;
+ }
+ }
+
+ if(repOnKill.repfaction2)
+ {
+ FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(repOnKill.repfaction2);
+ if(!factionEntry2)
+ {
+ sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction2);
+ continue;
+ }
+ }
+
+ mRepOnKill[creature_id] = repOnKill;
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u creature award reputation definitions", count);
+}
+
+void ObjectMgr::LoadWeatherZoneChances()
+{
+ uint32 count = 0;
+
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12
+ QueryResult *result = WorldDatabase.Query("SELECT zone, spring_rain_chance, spring_snow_chance, spring_storm_chance, summer_rain_chance, summer_snow_chance, summer_storm_chance, fall_rain_chance, fall_snow_chance, fall_storm_chance, winter_rain_chance, winter_snow_chance, winter_storm_chance FROM game_weather");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 weather definitions. DB table `game_weather` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 zone_id = fields[0].GetUInt32();
+
+ WeatherZoneChances& wzc = mWeatherZoneMap[zone_id];
+
+ for(int season = 0; season < WEATHER_SEASONS; ++season)
+ {
+ wzc.data[season].rainChance = fields[season * (MAX_WEATHER_TYPE-1) + 1].GetUInt32();
+ wzc.data[season].snowChance = fields[season * (MAX_WEATHER_TYPE-1) + 2].GetUInt32();
+ wzc.data[season].stormChance = fields[season * (MAX_WEATHER_TYPE-1) + 3].GetUInt32();
+
+ if(wzc.data[season].rainChance > 100)
+ {
+ wzc.data[season].rainChance = 25;
+ sLog.outErrorDb("Weather for zone %u season %u has wrong rain chance > 100%",zone_id,season);
+ }
+
+ if(wzc.data[season].snowChance > 100)
+ {
+ wzc.data[season].snowChance = 25;
+ sLog.outErrorDb("Weather for zone %u season %u has wrong snow chance > 100%",zone_id,season);
+ }
+
+ if(wzc.data[season].stormChance > 100)
+ {
+ wzc.data[season].stormChance = 25;
+ sLog.outErrorDb("Weather for zone %u season %u has wrong storm chance > 100%",zone_id,season);
+ }
+ }
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u weather definitions", count);
+}
+
+void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t)
+{
+ mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = t;
+ WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance);
+ if(t)
+ WorldDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance);
+}
+
+void ObjectMgr::DeleteCreatureData(uint32 guid)
+{
+ // remove mapid*cellid -> guid_set map
+ CreatureData const* data = GetCreatureData(guid);
+ if(data)
+ RemoveCreatureFromGrid(guid, data);
+
+ mCreatureDataMap.erase(guid);
+}
+
+void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t)
+{
+ mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = t;
+ WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance);
+ if(t)
+ WorldDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance);
+}
+
+void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance)
+{
+ RespawnTimes::iterator next;
+
+ for(RespawnTimes::iterator itr = mGORespawnTimes.begin(); itr != mGORespawnTimes.end(); itr = next)
+ {
+ next = itr;
+ ++next;
+
+ if(GUID_HIPART(itr->first)==instance)
+ mGORespawnTimes.erase(itr);
+ }
+
+ for(RespawnTimes::iterator itr = mCreatureRespawnTimes.begin(); itr != mCreatureRespawnTimes.end(); itr = next)
+ {
+ next = itr;
+ ++next;
+
+ if(GUID_HIPART(itr->first)==instance)
+ mCreatureRespawnTimes.erase(itr);
+ }
+
+ WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", instance);
+ WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", instance);
+}
+
+void ObjectMgr::DeleteGOData(uint32 guid)
+{
+ // remove mapid*cellid -> guid_set map
+ GameObjectData const* data = GetGOData(guid);
+ if(data)
+ RemoveGameobjectFromGrid(guid, data);
+
+ mGameObjectDataMap.erase(guid);
+}
+
+void ObjectMgr::AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance)
+{
+ // corpses are always added to spawn mode 0 and they are spawned by their instance id
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(mapid,0)][cellid];
+ cell_guids.corpses[player_guid] = instance;
+}
+
+void ObjectMgr::DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid)
+{
+ // corpses are always added to spawn mode 0 and they are spawned by their instance id
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(mapid,0)][cellid];
+ cell_guids.corpses.erase(player_guid);
+}
+
+void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map,char const* table)
+{
+ map.clear(); // need for reload case
+
+ uint32 count = 0;
+
+ QueryResult *result = WorldDatabase.PQuery("SELECT id,quest FROM %s",table);
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 quest relations from %s. DB table `%s` is empty.",table,table);
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 id = fields[0].GetUInt32();
+ uint32 quest = fields[1].GetUInt32();
+
+ if(mQuestTemplates.find(quest) == mQuestTemplates.end())
+ {
+ sLog.outErrorDb("Table `%s: Quest %u listed for entry %u does not exist.",table,quest,id);
+ continue;
+ }
+
+ map.insert(QuestRelations::value_type(id,quest));
+
+ ++count;
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u quest relations from %s", count,table);
+}
+
+void ObjectMgr::LoadGameobjectQuestRelations()
+{
+ LoadQuestRelationsHelper(mGOQuestRelations,"gameobject_questrelation");
+
+ for(QuestRelations::iterator itr = mGOQuestRelations.begin(); itr != mGOQuestRelations.end(); ++itr)
+ {
+ GameObjectInfo const* goInfo = GetGameObjectInfo(itr->first);
+ if(!goInfo)
+ sLog.outErrorDb("Table `gameobject_questrelation` have data for not existed gameobject entry (%u) and existed quest %u",itr->first,itr->second);
+ else if(goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
+ sLog.outErrorDb("Table `gameobject_questrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER",itr->first,itr->second);
+ }
+}
+
+void ObjectMgr::LoadGameobjectInvolvedRelations()
+{
+ LoadQuestRelationsHelper(mGOQuestInvolvedRelations,"gameobject_involvedrelation");
+
+ for(QuestRelations::iterator itr = mGOQuestInvolvedRelations.begin(); itr != mGOQuestInvolvedRelations.end(); ++itr)
+ {
+ GameObjectInfo const* goInfo = GetGameObjectInfo(itr->first);
+ if(!goInfo)
+ sLog.outErrorDb("Table `gameobject_involvedrelation` have data for not existed gameobject entry (%u) and existed quest %u",itr->first,itr->second);
+ else if(goInfo->type != GAMEOBJECT_TYPE_QUESTGIVER)
+ sLog.outErrorDb("Table `gameobject_involvedrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER",itr->first,itr->second);
+ }
+}
+
+void ObjectMgr::LoadCreatureQuestRelations()
+{
+ LoadQuestRelationsHelper(mCreatureQuestRelations,"creature_questrelation");
+
+ for(QuestRelations::iterator itr = mCreatureQuestRelations.begin(); itr != mCreatureQuestRelations.end(); ++itr)
+ {
+ CreatureInfo const* cInfo = GetCreatureTemplate(itr->first);
+ if(!cInfo)
+ sLog.outErrorDb("Table `creature_questrelation` have data for not existed creature entry (%u) and existed quest %u",itr->first,itr->second);
+ else if(!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
+ sLog.outErrorDb("Table `creature_questrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER",itr->first,itr->second);
+ }
+}
+
+void ObjectMgr::LoadCreatureInvolvedRelations()
+{
+ LoadQuestRelationsHelper(mCreatureQuestInvolvedRelations,"creature_involvedrelation");
+
+ for(QuestRelations::iterator itr = mCreatureQuestInvolvedRelations.begin(); itr != mCreatureQuestInvolvedRelations.end(); ++itr)
+ {
+ CreatureInfo const* cInfo = GetCreatureTemplate(itr->first);
+ if(!cInfo)
+ sLog.outErrorDb("Table `creature_involvedrelation` have data for not existed creature entry (%u) and existed quest %u",itr->first,itr->second);
+ else if(!(cInfo->npcflag & UNIT_NPC_FLAG_QUESTGIVER))
+ sLog.outErrorDb("Table `creature_involvedrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER",itr->first,itr->second);
+ }
+}
+
+void ObjectMgr::LoadReservedPlayersNames()
+{
+ m_ReservedNames.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT name FROM reserved_name");
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u reserved player names", count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ Field* fields;
+ do
+ {
+ bar.step();
+ fields = result->Fetch();
+ std::string name= fields[0].GetCppString();
+ if(normalizePlayerName(name))
+ {
+ m_ReservedNames.insert(name);
+ ++count;
+ }
+ } while ( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u reserved player names", count );
+}
+
+enum LanguageType
+{
+ LT_BASIC_LATIN = 0x0000,
+ LT_EXTENDEN_LATIN = 0x0001,
+ LT_CYRILLIC = 0x0002,
+ LT_EAST_ASIA = 0x0004,
+ LT_ANY = 0xFFFF
+};
+
+static LanguageType GetRealmLanguageType(bool create)
+{
+ switch(sWorld.getConfig(CONFIG_REALM_ZONE))
+ {
+ case REALM_ZONE_UNKNOWN: // any language
+ case REALM_ZONE_DEVELOPMENT:
+ case REALM_ZONE_TEST_SERVER:
+ case REALM_ZONE_QA_SERVER:
+ return LT_ANY;
+ case REALM_ZONE_UNITED_STATES: // extended-Latin
+ case REALM_ZONE_OCEANIC:
+ case REALM_ZONE_LATIN_AMERICA:
+ case REALM_ZONE_ENGLISH:
+ case REALM_ZONE_GERMAN:
+ case REALM_ZONE_FRENCH:
+ case REALM_ZONE_SPANISH:
+ return LT_EXTENDEN_LATIN;
+ case REALM_ZONE_KOREA: // East-Asian
+ case REALM_ZONE_TAIWAN:
+ case REALM_ZONE_CHINA:
+ return LT_EAST_ASIA;
+ case REALM_ZONE_RUSSIAN: // Cyrillic
+ return LT_CYRILLIC;
+ default:
+ return create ? LT_BASIC_LATIN : LT_ANY; // basic-Latin at create, any at login
+ }
+}
+
+bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create = false)
+{
+ if(strictMask==0) // any language, ignore realm
+ {
+ if(isExtendedLatinString(wstr,numericOrSpace))
+ return true;
+ if(isCyrillicString(wstr,numericOrSpace))
+ return true;
+ if(isEastAsianString(wstr,numericOrSpace))
+ return true;
+ return false;
+ }
+
+ if(strictMask & 0x2) // realm zone specific
+ {
+ LanguageType lt = GetRealmLanguageType(create);
+ if(lt & LT_EXTENDEN_LATIN)
+ if(isExtendedLatinString(wstr,numericOrSpace))
+ return true;
+ if(lt & LT_CYRILLIC)
+ if(isCyrillicString(wstr,numericOrSpace))
+ return true;
+ if(lt & LT_EAST_ASIA)
+ if(isEastAsianString(wstr,numericOrSpace))
+ return true;
+ }
+
+ if(strictMask & 0x1) // basic Latin
+ {
+ if(isBasicLatinString(wstr,numericOrSpace))
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectMgr::IsValidName( std::string name, bool create )
+{
+ std::wstring wname;
+ if(!Utf8toWStr(name,wname))
+ return false;
+
+ if(wname.size() < 1 || wname.size() > MAX_PLAYER_NAME)
+ return false;
+
+ uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_PLAYER_NAMES);
+
+ return isValidString(wname,strictMask,false,create);
+}
+
+bool ObjectMgr::IsValidCharterName( std::string name )
+{
+ std::wstring wname;
+ if(!Utf8toWStr(name,wname))
+ return false;
+
+ if(wname.size() < 1)
+ return false;
+
+ uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_CHARTER_NAMES);
+
+ return isValidString(wname,strictMask,true);
+}
+
+bool ObjectMgr::IsValidPetName( std::string name )
+{
+ std::wstring wname;
+ if(!Utf8toWStr(name,wname))
+ return false;
+
+ if(wname.size() < 1)
+ return false;
+
+ uint32 strictMask = sWorld.getConfig(CONFIG_STRICT_PET_NAMES);
+
+ return isValidString(wname,strictMask,false);
+}
+
+int ObjectMgr::GetIndexForLocale( LocaleConstant loc )
+{
+ if(loc==LOCALE_enUS)
+ return -1;
+
+ for(size_t i=0;i < m_LocalForIndex.size(); ++i)
+ if(m_LocalForIndex[i]==loc)
+ return i;
+
+ return -1;
+}
+
+LocaleConstant ObjectMgr::GetLocaleForIndex(int i)
+{
+ if (i<0 || i>=m_LocalForIndex.size())
+ return LOCALE_enUS;
+
+ return m_LocalForIndex[i];
+}
+
+int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc )
+{
+ if(loc==LOCALE_enUS)
+ return -1;
+
+ for(size_t i=0;i < m_LocalForIndex.size(); ++i)
+ if(m_LocalForIndex[i]==loc)
+ return i;
+
+ m_LocalForIndex.push_back(loc);
+ return m_LocalForIndex.size()-1;
+}
+
+void ObjectMgr::LoadBattleMastersEntry()
+{
+ mBattleMastersMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" );
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ uint32 bgTypeId = fields[1].GetUInt32();
+
+ mBattleMastersMap[entry] = bgTypeId;
+
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u battlemaster entries", count );
+}
+
+void ObjectMgr::LoadGameObjectForQuests()
+{
+ mGameObjectForQuestSet.clear(); // need for reload case
+
+ uint32 count = 0;
+
+ // collect GO entries for GO that must activated
+ for(uint32 go_entry = 1; go_entry < sGOStorage.MaxEntry; ++go_entry)
+ {
+ GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(go_entry);
+ if(!goInfo)
+ continue;
+
+ switch(goInfo->type)
+ {
+ // scan GO chest with loot including quest items
+ case GAMEOBJECT_TYPE_CHEST:
+ {
+ uint32 loot_id = GameObject::GetLootId(goInfo);
+
+ // find quest loot for GO
+ if(LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
+ {
+ mGameObjectForQuestSet.insert(go_entry);
+ ++count;
+ }
+ break;
+ }
+ case GAMEOBJECT_TYPE_GOOBER:
+ {
+ if(goInfo->goober.questId) //quests objects
+ {
+ mGameObjectForQuestSet.insert(go_entry);
+ count++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u GameObject for quests", count );
+}
+
+bool ObjectMgr::LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value)
+{
+ // cleanup affected map part for reloading case
+ for(TrinityStringLocaleMap::iterator itr = mTrinityStringLocaleMap.begin(); itr != mTrinityStringLocaleMap.end();)
+ {
+ if(itr->first >= min_value && itr->first <= max_value)
+ {
+ TrinityStringLocaleMap::iterator itr2 = itr;
+ ++itr;
+ mTrinityStringLocaleMap.erase(itr2);
+ }
+ else
+ ++itr;
+ }
+
+ QueryResult *result = db.PQuery("SELECT entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8 FROM %s",table);
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ if(min_value > 0) // error only in case internal strings
+ sLog.outErrorDb(">> Loaded 0 trinity strings. DB table `%s` is empty. Cannot continue.",table);
+ else
+ sLog.outString(">> Loaded 0 string templates. DB table `%s` is empty.",table);
+ return false;
+ }
+
+ uint32 count = 0;
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ int32 entry = fields[0].GetInt32();
+
+ if(entry==0)
+ {
+ sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.",table);
+ continue;
+ }
+ else if(entry < min_value || entry > max_value)
+ {
+ int32 start = min_value > 0 ? min_value : max_value;
+ int32 end = min_value > 0 ? max_value : min_value;
+ sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,start,end);
+ continue;
+ }
+
+ TrinityStringLocale& data = mTrinityStringLocaleMap[entry];
+
+ if(data.Content.size() > 0)
+ {
+ sLog.outErrorDb("Table `%s` contain data for already loaded entry %i (from another table?), ignored.",table,entry);
+ continue;
+ }
+
+ data.Content.resize(1);
+ ++count;
+
+ // 0 -> default, idx in to idx+1
+ data.Content[0] = fields[1].GetCppString();
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[i+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ // 0 -> default, idx in to idx+1
+ if(data.Content.size() <= idx+1)
+ data.Content.resize(idx+2);
+
+ data.Content[idx+1] = str;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ if(min_value > 0) // internal Trinity strings
+ sLog.outString( ">> Loaded %u Trinity strings from table %s", count,table);
+ else
+ sLog.outString( ">> Loaded %u string templates from %s", count,table);
+
+ return true;
+}
+
+const char *ObjectMgr::GetTrinityString(int32 entry, int locale_idx) const
+{
+ // locale_idx==-1 -> default, locale_idx >= 0 in to idx+1
+ // Content[0] always exist if exist TrinityStringLocale
+ if(TrinityStringLocale const *msl = GetTrinityStringLocale(entry))
+ {
+ if(msl->Content.size() > locale_idx+1 && !msl->Content[locale_idx+1].empty())
+ return msl->Content[locale_idx+1].c_str();
+ else
+ return msl->Content[0].c_str();
+ }
+
+ if(entry > 0)
+ sLog.outErrorDb("Entry %i not found in `trinity_string` table.",entry);
+ else
+ sLog.outErrorDb("Trinity string entry %i not found in DB.",entry);
+ return "<error>";
+}
+
+void ObjectMgr::LoadSpellDisabledEntrys()
+{
+ m_DisabledPlayerSpells.clear(); // need for reload case
+ m_DisabledCreatureSpells.clear();
+ QueryResult *result = WorldDatabase.Query("SELECT entry, disable_mask FROM spell_disabled");
+
+ uint32 total_count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u disabled spells", total_count );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ Field* fields;
+ do
+ {
+ bar.step();
+ fields = result->Fetch();
+ uint32 spellid = fields[0].GetUInt32();
+ if(!sSpellStore.LookupEntry(spellid))
+ {
+ sLog.outErrorDb("Spell entry %u from `spell_disabled` doesn't exist in dbc, ignoring.",spellid);
+ continue;
+ }
+ uint32 disable_mask = fields[1].GetUInt32();
+ if(disable_mask & SPELL_DISABLE_PLAYER)
+ m_DisabledPlayerSpells.insert(spellid);
+ if(disable_mask & SPELL_DISABLE_CREATURE)
+ m_DisabledCreatureSpells.insert(spellid);
+ ++total_count;
+ } while ( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u disabled spells from `spell_disabled`", total_count);
+}
+
+void ObjectMgr::LoadFishingBaseSkillLevel()
+{
+ mFishingBaseForArea.clear(); // for reload case
+
+ uint32 count = 0;
+ QueryResult *result = WorldDatabase.Query("SELECT entry,skill FROM skill_fishing_base_level");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `skill_fishing_base_level`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+ uint32 entry = fields[0].GetUInt32();
+ int32 skill = fields[1].GetInt32();
+
+ AreaTableEntry const* fArea = GetAreaEntryByAreaID(entry);
+ if(!fArea)
+ {
+ sLog.outErrorDb("AreaId %u defined in `skill_fishing_base_level` does not exist",entry);
+ continue;
+ }
+
+ mFishingBaseForArea[entry] = skill;
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u areas for fishing base skill level", count );
+}
+
+// Searches for the same condition already in Conditions store
+// Returns Id if found, else adds it to Conditions and returns Id
+uint16 ObjectMgr::GetConditionId( ConditionType condition, uint32 value1, uint32 value2 )
+{
+ PlayerCondition lc = PlayerCondition(condition, value1, value2);
+ for (uint16 i=0; i < mConditions.size(); ++i)
+ {
+ if (lc == mConditions[i])
+ return i;
+ }
+
+ mConditions.push_back(lc);
+
+ if(mConditions.size() > 0xFFFF)
+ {
+ sLog.outError("Conditions store overflow! Current and later loaded conditions will ignored!");
+ return 0;
+ }
+
+ return mConditions.size() - 1;
+}
+
+bool ObjectMgr::CheckDeclinedNames( std::wstring mainpart, DeclinedName const& names )
+{
+ for(int i =0; i < MAX_DECLINED_NAME_CASES; ++i)
+ {
+ std::wstring wname;
+ if(!Utf8toWStr(names.name[i],wname))
+ return false;
+
+ if(mainpart!=GetMainPartOfName(wname,i+1))
+ return false;
+ }
+ return true;
+}
+
+uint32 ObjectMgr::GetAreaTriggerScriptId(uint32 trigger_id)
+{
+ AreaTriggerScriptMap::const_iterator i = mAreaTriggerScripts.find(trigger_id);
+ if(i!= mAreaTriggerScripts.end())
+ return i->second;
+ return 0;
+}
+
+// Checks if player meets the condition
+bool PlayerCondition::Meets(Player const * player) const
+{
+ if( !player )
+ return false; // player not present, return false
+
+ switch (condition)
+ {
+ case CONDITION_NONE:
+ return true; // empty condition, always met
+ case CONDITION_AURA:
+ return player->HasAura(value1, value2);
+ case CONDITION_ITEM:
+ return player->HasItemCount(value1, value2);
+ case CONDITION_ITEM_EQUIPPED:
+ return player->GetItemOrItemWithGemEquipped(value1) != NULL;
+ case CONDITION_ZONEID:
+ return player->GetZoneId() == value1;
+ case CONDITION_REPUTATION_RANK:
+ {
+ FactionEntry const* faction = sFactionStore.LookupEntry(value1);
+ return faction && player->GetReputationRank(faction) >= value2;
+ }
+ case CONDITION_TEAM:
+ return player->GetTeam() == value1;
+ case CONDITION_SKILL:
+ return player->HasSkill(value1) && player->GetBaseSkillValue(value1) >= value2;
+ case CONDITION_QUESTREWARDED:
+ return player->GetQuestRewardStatus(value1);
+ case CONDITION_QUESTTAKEN:
+ {
+ QuestStatus status = player->GetQuestStatus(value1);
+ return (status == QUEST_STATUS_INCOMPLETE);
+ }
+ case CONDITION_AD_COMMISSION_AURA:
+ {
+ Unit::AuraMap const& auras = player->GetAuras();
+ for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580)
+ return true;
+ return false;
+ }
+ case CONDITION_NO_AURA:
+ return !player->HasAura(value1, value2);
+ case CONDITION_ACTIVE_EVENT:
+ return gameeventmgr.IsActiveEvent(value1);
+ default:
+ return false;
+ }
+}
+
+// Verification of condition values validity
+bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 value2)
+{
+ if( condition >= MAX_CONDITION) // Wrong condition type
+ {
+ sLog.outErrorDb("Condition has bad type of %u, skipped ", condition );
+ return false;
+ }
+
+ switch (condition)
+ {
+ case CONDITION_AURA:
+ {
+ if(!sSpellStore.LookupEntry(value1))
+ {
+ sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1);
+ return false;
+ }
+ if(value2 > 2)
+ {
+ sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_ITEM:
+ {
+ ItemPrototype const *proto = objmgr.GetItemPrototype(value1);
+ if(!proto)
+ {
+ sLog.outErrorDb("Item condition requires to have non existing item (%u), skipped", value1);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_ITEM_EQUIPPED:
+ {
+ ItemPrototype const *proto = objmgr.GetItemPrototype(value1);
+ if(!proto)
+ {
+ sLog.outErrorDb("ItemEquipped condition requires to have non existing item (%u) equipped, skipped", value1);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_ZONEID:
+ {
+ AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(value1);
+ if(!areaEntry)
+ {
+ sLog.outErrorDb("Zone condition requires to be in non existing area (%u), skipped", value1);
+ return false;
+ }
+ if(areaEntry->zone != 0)
+ {
+ sLog.outErrorDb("Zone condition requires to be in area (%u) which is a subzone but zone expected, skipped", value1);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_REPUTATION_RANK:
+ {
+ FactionEntry const* factionEntry = sFactionStore.LookupEntry(value1);
+ if(!factionEntry)
+ {
+ sLog.outErrorDb("Reputation condition requires to have reputation non existing faction (%u), skipped", value1);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_TEAM:
+ {
+ if (value1 != ALLIANCE && value1 != HORDE)
+ {
+ sLog.outErrorDb("Team condition specifies unknown team (%u), skipped", value1);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_SKILL:
+ {
+ SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(value1);
+ if (!pSkill)
+ {
+ sLog.outErrorDb("Skill condition specifies non-existing skill (%u), skipped", value1);
+ return false;
+ }
+ if (value2 < 1 || value2 > sWorld.GetConfigMaxSkillValue() )
+ {
+ sLog.outErrorDb("Skill condition specifies invalid skill value (%u), skipped", value2);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_QUESTREWARDED:
+ case CONDITION_QUESTTAKEN:
+ {
+ Quest const *Quest = objmgr.GetQuestTemplate(value1);
+ if (!Quest)
+ {
+ sLog.outErrorDb("Quest condition specifies non-existing quest (%u), skipped", value1);
+ return false;
+ }
+ if(value2)
+ sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2);
+ break;
+ }
+ case CONDITION_AD_COMMISSION_AURA:
+ {
+ if(value1)
+ sLog.outErrorDb("Quest condition has useless data in value1 (%u)!", value1);
+ if(value2)
+ sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2);
+ break;
+ }
+ case CONDITION_NO_AURA:
+ {
+ if(!sSpellStore.LookupEntry(value1))
+ {
+ sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1);
+ return false;
+ }
+ if(value2 > 2)
+ {
+ sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2);
+ return false;
+ }
+ break;
+ }
+ case CONDITION_ACTIVE_EVENT:
+ {
+ GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
+ if(value1 >=events.size() || !events[value1].isValid())
+ {
+ sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1);
+ return false;
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
+{
+ switch(pSkill->categoryId)
+ {
+ case SKILL_CATEGORY_LANGUAGES: return SKILL_RANGE_LANGUAGE;
+ case SKILL_CATEGORY_WEAPON:
+ if(pSkill->id!=SKILL_FIST_WEAPONS)
+ return SKILL_RANGE_LEVEL;
+ else
+ return SKILL_RANGE_MONO;
+ case SKILL_CATEGORY_ARMOR:
+ case SKILL_CATEGORY_CLASS:
+ if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING)
+ return SKILL_RANGE_MONO;
+ else
+ return SKILL_RANGE_LEVEL;
+ case SKILL_CATEGORY_SECONDARY:
+ case SKILL_CATEGORY_PROFESSION:
+ // not set skills for professions and racial abilities
+ if(IsProfessionSkill(pSkill->id))
+ return SKILL_RANGE_RANK;
+ else if(racial)
+ return SKILL_RANGE_NONE;
+ else
+ return SKILL_RANGE_MONO;
+ default:
+ case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc
+ case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND)
+ return SKILL_RANGE_NONE;
+ }
+}
+
+void ObjectMgr::LoadGameTele()
+{
+ m_GameTeleMap.clear(); // for reload case
+
+ uint32 count = 0;
+ QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `game_tele`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 id = fields[0].GetUInt32();
+
+ GameTele gt;
+
+ gt.position_x = fields[1].GetFloat();
+ gt.position_y = fields[2].GetFloat();
+ gt.position_z = fields[3].GetFloat();
+ gt.orientation = fields[4].GetFloat();
+ gt.mapId = fields[5].GetUInt32();
+ gt.name = fields[6].GetCppString();
+
+ if(!MapManager::IsValidMapCoord(gt.mapId,gt.position_x,gt.position_y,gt.position_z,gt.orientation))
+ {
+ sLog.outErrorDb("Wrong position for id %u (name: %s) in `game_tele` table, ignoring.",id,gt.name.c_str());
+ continue;
+ }
+
+ if(!Utf8toWStr(gt.name,gt.wnameLow))
+ {
+ sLog.outErrorDb("Wrong UTF8 name for id %u in `game_tele` table, ignoring.",id);
+ continue;
+ }
+
+ wstrToLower( gt.wnameLow );
+
+ m_GameTeleMap[id] = gt;
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u game tele's", count );
+}
+
+GameTele const* ObjectMgr::GetGameTele(std::string name) const
+{
+ // explicit name case
+ std::wstring wname;
+ if(!Utf8toWStr(name,wname))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower( wname );
+
+ // Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
+ const GameTele* alt = NULL;
+ for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr)
+ {
+ if(itr->second.wnameLow == wname)
+ return &itr->second;
+ else if (alt == NULL && itr->second.wnameLow.find(wname) != std::wstring::npos)
+ alt = &itr->second;
+ }
+
+ return alt;
+}
+
+bool ObjectMgr::AddGameTele(GameTele& tele)
+{
+ // find max id
+ uint32 new_id = 0;
+ for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr)
+ if(itr->first > new_id)
+ new_id = itr->first;
+
+ // use next
+ ++new_id;
+
+ if(!Utf8toWStr(tele.name,tele.wnameLow))
+ return false;
+
+ wstrToLower( tele.wnameLow );
+
+ m_GameTeleMap[new_id] = tele;
+
+ return WorldDatabase.PExecuteLog("INSERT INTO game_tele (id,position_x,position_y,position_z,orientation,map,name) VALUES (%u,%f,%f,%f,%f,%d,'%s')",
+ new_id,tele.position_x,tele.position_y,tele.position_z,tele.orientation,tele.mapId,tele.name.c_str());
+}
+
+bool ObjectMgr::DeleteGameTele(std::string name)
+{
+ // explicit name case
+ std::wstring wname;
+ if(!Utf8toWStr(name,wname))
+ return false;
+
+ // converting string that we try to find to lower case
+ wstrToLower( wname );
+
+ for(GameTeleMap::iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr)
+ {
+ if(itr->second.wnameLow == wname)
+ {
+ WorldDatabase.PExecuteLog("DELETE FROM game_tele WHERE name = '%s'",itr->second.name.c_str());
+ m_GameTeleMap.erase(itr);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ObjectMgr::LoadTrainerSpell()
+{
+ // For reload case
+ for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
+ itr->second.Clear();
+ m_mCacheTrainerSpellMap.clear();
+
+ std::set<uint32> skip_trainers;
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `npc_trainer`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ uint32 count = 0;
+ do
+ {
+ bar.step();
+
+ Field* fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ uint32 spell = fields[1].GetUInt32();
+
+ CreatureInfo const* cInfo = GetCreatureTemplate(entry);
+
+ if(!cInfo)
+ {
+ sLog.outErrorDb("Table `npc_trainer` have entry for not existed creature template (Entry: %u), ignore", entry);
+ continue;
+ }
+
+ if(!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
+ {
+ if(skip_trainers.count(entry) == 0)
+ {
+ sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry);
+ skip_trainers.insert(entry);
+ }
+ continue;
+ }
+
+ SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell);
+ if(!spellinfo)
+ {
+ sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u ) has non existing spell %u, ignore", entry,spell);
+ continue;
+ }
+
+ if(!SpellMgr::IsSpellValid(spellinfo))
+ {
+ sLog.outErrorDb("Table `npc_trainer` for Trainer (Entry: %u) has broken learning spell %u, ignore", entry, spell);
+ continue;
+ }
+
+ TrainerSpell* pTrainerSpell = new TrainerSpell();
+ pTrainerSpell->spell = spell;
+ pTrainerSpell->spellcost = fields[2].GetUInt32();
+ pTrainerSpell->reqskill = fields[3].GetUInt32();
+ pTrainerSpell->reqskillvalue = fields[4].GetUInt32();
+ pTrainerSpell->reqlevel = fields[5].GetUInt32();
+
+ if(!pTrainerSpell->reqlevel)
+ pTrainerSpell->reqlevel = spellinfo->spellLevel;
+
+
+ TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];
+
+ if(SpellMgr::IsProfessionSpell(spell))
+ data.trainerType = 2;
+
+ data.spellList.push_back(pTrainerSpell);
+ ++count;
+
+ } while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded Trainers %d", count );
+}
+
+void ObjectMgr::LoadVendors()
+{
+ // For reload case
+ for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
+ itr->second.Clear();
+ m_mCacheVendorItemMap.clear();
+
+ std::set<uint32> skip_vendors;
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `npc_vendor`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ uint32 count = 0;
+ do
+ {
+ bar.step();
+ Field* fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ uint32 item_id = fields[1].GetUInt32();
+ uint32 maxcount = fields[2].GetUInt32();
+ uint32 incrtime = fields[3].GetUInt32();
+ uint32 ExtendedCost = fields[4].GetUInt32();
+
+ if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors))
+ continue;
+
+ VendorItemData& vList = m_mCacheVendorItemMap[entry];
+
+ vList.AddItem(item_id,maxcount,incrtime,ExtendedCost);
+ ++count;
+
+ } while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %d Vendors ", count );
+}
+
+void ObjectMgr::LoadNpcTextId()
+{
+
+ m_mCacheNpcTextIdMap.clear();
+
+ QueryResult* result = WorldDatabase.Query("SELECT npc_guid, textid FROM npc_gossip");
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `npc_gossip`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ uint32 count = 0;
+ uint32 guid,textid;
+ do
+ {
+ bar.step();
+
+ Field* fields = result->Fetch();
+
+ guid = fields[0].GetUInt32();
+ textid = fields[1].GetUInt32();
+
+ if (!GetCreatureData(guid))
+ {
+ sLog.outErrorDb("Table `npc_gossip` have not existed creature (GUID: %u) entry, ignore. ",guid);
+ continue;
+ }
+ if (!GetGossipText(textid))
+ {
+ sLog.outErrorDb("Table `npc_gossip` for creature (GUID: %u) have wrong Textid (%u), ignore. ", guid, textid);
+ continue;
+ }
+
+ m_mCacheNpcTextIdMap[guid] = textid ;
+ ++count;
+
+ } while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %d NpcTextId ", count );
+}
+
+void ObjectMgr::LoadNpcOptions()
+{
+ m_mCacheNpcOptionList.clear(); // For reload case
+
+ QueryResult *result = WorldDatabase.Query(
+ // 0 1 2 3 4 5 6 7 8
+ "SELECT id,gossip_id,npcflag,icon,action,box_money,coded,option_text,box_text "
+ "FROM npc_option");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `npc_option`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ uint32 count = 0;
+
+ do
+ {
+ bar.step();
+
+ Field* fields = result->Fetch();
+
+ GossipOption go;
+ go.Id = fields[0].GetUInt32();
+ go.GossipId = fields[1].GetUInt32();
+ go.NpcFlag = fields[2].GetUInt32();
+ go.Icon = fields[3].GetUInt32();
+ go.Action = fields[4].GetUInt32();
+ go.BoxMoney = fields[5].GetUInt32();
+ go.Coded = fields[6].GetUInt8()!=0;
+ go.OptionText = fields[7].GetCppString();
+ go.BoxText = fields[8].GetCppString();
+
+ m_mCacheNpcOptionList.push_back(go);
+
+ ++count;
+
+ } while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %d npc_option entries", count );
+}
+
+void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost, bool savetodb)
+{
+ VendorItemData& vList = m_mCacheVendorItemMap[entry];
+ vList.AddItem(item,maxcount,incrtime,extendedcost);
+
+ if(savetodb) WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost);
+}
+
+bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item, bool savetodb)
+{
+ CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry);
+ if(iter == m_mCacheVendorItemMap.end())
+ return false;
+
+ if(!iter->second.FindItem(item))
+ return false;
+
+ iter->second.RemoveItem(item);
+ if(savetodb) WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item);
+ return true;
+}
+
+bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set<uint32>* skip_vendors, uint32 ORnpcflag ) const
+{
+ CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry);
+ if(!cInfo)
+ {
+ if(pl)
+ ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
+ else
+ sLog.outErrorDb("Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry);
+ return false;
+ }
+
+ if(!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR))
+ {
+ if(!skip_vendors || skip_vendors->count(vendor_entry)==0)
+ {
+ if(pl)
+ ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
+ else
+ sLog.outErrorDb("Table `(game_event_)npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry);
+
+ if(skip_vendors)
+ skip_vendors->insert(vendor_entry);
+ }
+ return false;
+ }
+
+ if(!GetItemPrototype(item_id))
+ {
+ if(pl)
+ ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
+ else
+ sLog.outErrorDb("Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id);
+ return false;
+ }
+
+ if(ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
+ {
+ if(pl)
+ ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost);
+ else
+ sLog.outErrorDb("Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry);
+ return false;
+ }
+
+ if(maxcount > 0 && incrtime == 0)
+ {
+ if(pl)
+ ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount);
+ else
+ sLog.outErrorDb( "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry);
+ return false;
+ }
+ else if(maxcount==0 && incrtime > 0)
+ {
+ if(pl)
+ ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0");
+ else
+ sLog.outErrorDb( "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry);
+ return false;
+ }
+
+ VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
+ if(!vItems)
+ return true; // later checks for non-empty lists
+
+ if(vItems->FindItem(item_id))
+ {
+ if(pl)
+ ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,item_id);
+ else
+ sLog.outErrorDb( "Table `(game_event_)npc_vendor` has duplicate items %u for vendor (Entry: %u), ignore", item_id, vendor_entry);
+ return false;
+ }
+
+ if(vItems->GetItemCount() >= MAX_VENDOR_ITEMS)
+ {
+ if(pl)
+ ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
+ else
+ sLog.outErrorDb( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", vItems->GetItemCount(), MAX_VENDOR_ITEMS, vendor_entry);
+ return false;
+ }
+
+ return true;
+}
+
+void ObjectMgr::LoadScriptNames()
+{
+ m_scriptNames.push_back("");
+ QueryResult *result = WorldDatabase.Query(
+ "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
+ if(result)
+ {
+ do
+ {
+ m_scriptNames.push_back((*result)[0].GetString());
+ } while (result->NextRow());
+ delete result;
+ }
+
+ std::sort(m_scriptNames.begin(), m_scriptNames.end());
+}
+
+uint32 ObjectMgr::GetScriptId(const char *name)
+{
+ // use binary search to find the script name in the sorted vector
+ // assume "" is the first element
+ if(!name) return 0;
+ ScriptNameMap::const_iterator itr =
+ std::lower_bound(m_scriptNames.begin(), m_scriptNames.end(), name);
+ if(itr == m_scriptNames.end()) return 0;
+ return itr - m_scriptNames.begin();
+}
+
+void ObjectMgr::CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids)
+{
+ for(ScriptMapMap::const_iterator itrMM = scripts.begin(); itrMM != scripts.end(); ++itrMM)
+ {
+ for(ScriptMap::const_iterator itrM = itrMM->second.begin(); itrM != itrMM->second.end(); ++itrM)
+ {
+ if(itrM->second.dataint)
+ {
+ if(!GetTrinityStringLocale (itrM->second.dataint))
+ sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", *itrM);
+
+ if(ids.count(itrM->second.dataint))
+ ids.erase(itrM->second.dataint);
+ }
+ }
+ }
+}
+
+void ObjectMgr::LoadDbScriptStrings()
+{
+ LoadTrinityStrings(WorldDatabase,"db_script_string",MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID);
+
+ std::set<int32> ids;
+
+ for(int32 i = MIN_DB_SCRIPT_STRING_ID; i < MAX_DB_SCRIPT_STRING_ID; ++i)
+ if(GetTrinityStringLocale(i))
+ ids.insert(i);
+
+ CheckScripts(sQuestEndScripts,ids);
+ CheckScripts(sQuestStartScripts,ids);
+ CheckScripts(sSpellScripts,ids);
+ CheckScripts(sGameObjectScripts,ids);
+ CheckScripts(sEventScripts,ids);
+
+ for(std::set<int32>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr)
+ sLog.outErrorDb( "Table `db_script_string` has unused string id %u", *itr);
+}
+
+// Functions for scripting access
+uint32 GetAreaTriggerScriptId(uint32 trigger_id)
+{
+ return objmgr.GetAreaTriggerScriptId(trigger_id);
+}
+
+bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value)
+{
+ if(start_value >= 0 || start_value <= end_value) // start/end reversed for negative values
+ {
+ sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), use (%d - %d) instead.",table,start_value,end_value,-1,std::numeric_limits<int32>::min());
+ start_value = -1;
+ end_value = std::numeric_limits<int32>::min();
+ }
+
+ // for scripting localized strings allowed use _only_ negative entries
+ return objmgr.LoadTrinityStrings(db,table,end_value,start_value);
+}
+
+uint32 TRINITY_DLL_SPEC GetScriptId(const char *name)
+{
+ return objmgr.GetScriptId(name);
+}
+
+ObjectMgr::ScriptNameMap & GetScriptNames()
+{
+ return objmgr.GetScriptNames();
+}
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index a5d8a679fdd..bed7eb9fbb8 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -1,913 +1,938 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _OBJECTMGR_H
-#define _OBJECTMGR_H
-
-#include "Log.h"
-#include "Object.h"
-#include "Bag.h"
-#include "Creature.h"
-#include "Player.h"
-#include "DynamicObject.h"
-#include "GameObject.h"
-#include "Corpse.h"
-#include "QuestDef.h"
-#include "Path.h"
-#include "ItemPrototype.h"
-#include "NPCHandler.h"
-#include "Database/DatabaseEnv.h"
-#include "AuctionHouseObject.h"
-#include "Mail.h"
-#include "Map.h"
-#include "ObjectAccessor.h"
-#include "ObjectDefines.h"
-#include "Policies/Singleton.h"
-#include "Database/SQLStorage.h"
-
-#include <string>
-#include <map>
-#include <limits>
-
-extern SQLStorage sCreatureStorage;
-extern SQLStorage sCreatureDataAddonStorage;
-extern SQLStorage sCreatureInfoAddonStorage;
-extern SQLStorage sCreatureModelStorage;
-extern SQLStorage sEquipmentStorage;
-extern SQLStorage sGOStorage;
-extern SQLStorage sPageTextStore;
-extern SQLStorage sItemStorage;
-extern SQLStorage sInstanceTemplate;
-
-class Group;
-class Guild;
-class ArenaTeam;
-class Path;
-class TransportPath;
-class Item;
-
-struct GameTele
-{
- float position_x;
- float position_y;
- float position_z;
- float orientation;
- uint32 mapId;
- std::string name;
- std::wstring wnameLow;
-};
-
-typedef UNORDERED_MAP<uint32, GameTele > GameTeleMap;
-typedef std::list<GossipOption> CacheNpcOptionList;
-
-struct ScriptInfo
-{
- uint32 id;
- uint32 delay;
- uint32 command;
- uint32 datalong;
- uint32 datalong2;
- std::string datatext;
- float x;
- float y;
- float z;
- float o;
-};
-
-typedef std::multimap<uint32, ScriptInfo> ScriptMap;
-typedef std::map<uint32, ScriptMap > ScriptMapMap;
-extern ScriptMapMap sQuestEndScripts;
-extern ScriptMapMap sQuestStartScripts;
-extern ScriptMapMap sSpellScripts;
-extern ScriptMapMap sGameObjectScripts;
-extern ScriptMapMap sEventScripts;
-
-struct AreaTrigger
-{
- uint8 requiredLevel;
- uint32 requiredItem;
- uint32 requiredItem2;
- uint32 heroicKey;
- uint32 heroicKey2;
- uint32 requiredQuest;
- std::string requiredFailedText;
- uint32 target_mapId;
- float target_X;
- float target_Y;
- float target_Z;
- float target_Orientation;
-};
-
-typedef std::set<uint32> CellGuidSet;
-typedef std::map<uint32/*player guid*/,uint32/*instance*/> CellCorpseSet;
-struct CellObjectGuids
-{
- CellGuidSet creatures;
- CellGuidSet gameobjects;
- CellCorpseSet corpses;
-};
-typedef UNORDERED_MAP<uint32/*cell_id*/,CellObjectGuids> CellObjectGuidsMap;
-typedef UNORDERED_MAP<uint32/*(mapid,spawnMode) pair*/,CellObjectGuidsMap> MapObjectGuids;
-
-typedef UNORDERED_MAP<uint64/*(instance,guid) pair*/,time_t> RespawnTimes;
-
-struct TrinityStringLocale
-{
- std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
-};
-
-typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
-typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
-typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
-typedef UNORDERED_MAP<uint32,GameObjectLocale> GameObjectLocaleMap;
-typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap;
-typedef UNORDERED_MAP<uint32,QuestLocale> QuestLocaleMap;
-typedef UNORDERED_MAP<uint32,NpcTextLocale> NpcTextLocaleMap;
-typedef UNORDERED_MAP<uint32,PageTextLocale> PageTextLocaleMap;
-typedef UNORDERED_MAP<uint32,TrinityStringLocale> TrinityStringLocaleMap;
-typedef UNORDERED_MAP<uint32,NpcOptionLocale> NpcOptionLocaleMap;
-
-typedef std::multimap<uint32,uint32> QuestRelations;
-
-struct PetLevelInfo
-{
- PetLevelInfo() : health(0), mana(0) { for(int i=0; i < MAX_STATS; ++i ) stats[i] = 0; }
-
- uint16 stats[MAX_STATS];
- uint16 health;
- uint16 mana;
- uint16 armor;
-};
-
-struct ReputationOnKillEntry
-{
- uint32 repfaction1;
- uint32 repfaction2;
- bool is_teamaward1;
- uint32 reputation_max_cap1;
- int32 repvalue1;
- bool is_teamaward2;
- uint32 reputation_max_cap2;
- int32 repvalue2;
- bool team_dependent;
-};
-
-struct PetCreateSpellEntry
-{
- uint32 spellid[4];
-};
-
-#define WEATHER_SEASONS 4
-struct WeatherSeasonChances
-{
- uint32 rainChance;
- uint32 snowChance;
- uint32 stormChance;
-};
-
-struct WeatherZoneChances
-{
- WeatherSeasonChances data[WEATHER_SEASONS];
-};
-
-struct GraveYardData
-{
- uint32 safeLocId;
- uint32 team;
-};
-typedef std::multimap<uint32,GraveYardData> GraveYardMap;
-
-enum ConditionType
-{ // value1 value2 for the Condition enumed
- CONDITION_NONE = 0, // 0 0
- CONDITION_AURA = 1, // spell_id effindex
- CONDITION_ITEM = 2, // item_id count
- CONDITION_ITEM_EQUIPPED = 3, // item_id 0
- CONDITION_ZONEID = 4, // zone_id 0
- CONDITION_REPUTATION_RANK = 5, // faction_id min_rank
- CONDITION_TEAM = 6, // player_team 0, (469 - Alliance 67 - Horde)
- CONDITION_SKILL = 7, // skill_id skill_value
- CONDITION_QUESTREWARDED = 8, // quest_id 0
- CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active.
- CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD ñommission aura active
- CONDITION_NO_AURA = 11, // spell_id effindex
- CONDITION_ACTIVE_EVENT = 12, // event_id
-};
-
-#define MAX_CONDITION 13 // maximum value in ConditionType enum
-
-//Player's info
-typedef struct _tagCachePlayerInfo
-{
- std::string sPlayerName;
- uint32 unfield;
- uint32 unLevel;
- uint8 unClass;
-//Arena
- uint32 unArenaInfoId0;
- uint32 unArenaInfoId1;
- uint32 unArenaInfoId2;
- uint32 unArenaInfoSlot0;
- uint32 unArenaInfoSlot1;
- uint32 unArenaInfoSlot2;
-}CachePlayerInfo, *PCachePlayerInfo;
-typedef UNORDERED_MAP<uint32, PCachePlayerInfo> CachePlayerInfoMap;
-
-struct PlayerCondition
-{
- ConditionType condition; // additional condition type
- uint32 value1; // data for the condition - see ConditionType definition
- uint32 value2;
-
- PlayerCondition(uint8 _condition = 0, uint32 _value1 = 0, uint32 _value2 = 0)
- : condition(ConditionType(_condition)), value1(_value1), value2(_value2) {}
-
- static bool IsValid(ConditionType condition, uint32 value1, uint32 value2);
- // Checks correctness of values
- bool Meets(Player const * APlayer) const; // Checks if the player meets the condition
- bool operator == (PlayerCondition const& lc) const
- {
- return (lc.condition == condition && lc.value1 == value1 && lc.value2 == value2);
- }
-};
-
-// NPC gossip text id
-typedef UNORDERED_MAP<uint32, uint32> CacheNpcTextIdMap;
-
-
-typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap;
-typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap;
-
-enum SkillRangeType
-{
- SKILL_RANGE_LANGUAGE, // 300..300
- SKILL_RANGE_LEVEL, // 1..max skill for level
- SKILL_RANGE_MONO, // 1..1, grey monolite bar
- SKILL_RANGE_RANK, // 1..skill for known rank
- SKILL_RANGE_NONE, // 0..0 always
-};
-
-SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial);
-
-#define MAX_PLAYER_NAME 12 // max allowed by client name length
-#define MAX_INTERNAL_PLAYER_NAME 15 // max server internal player name length ( > MAX_PLAYER_NAME for support declined names )
-
-bool normalizePlayerName(std::string& name);
-
-struct TRINITY_DLL_SPEC LanguageDesc
-{
- Language lang_id;
- uint32 spell_id;
- uint32 skill_id;
-};
-
-extern LanguageDesc lang_description[LANGUAGES_COUNT];
-TRINITY_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
-
-class PlayerDumpReader;
-
-class ObjectMgr
-{
- friend class PlayerDumpReader;
-
- public:
- ObjectMgr();
- ~ObjectMgr();
-
- typedef UNORDERED_MAP<uint32, Item*> ItemMap;
-
- typedef std::set< Group * > GroupSet;
- typedef std::set< Guild * > GuildSet;
- typedef std::set< ArenaTeam * > ArenaTeamSet;
-
- typedef UNORDERED_MAP<uint32, Quest*> QuestMap;
-
- typedef UNORDERED_MAP<uint32, AreaTrigger> AreaTriggerMap;
-
- typedef UNORDERED_MAP<uint32, std::string> AreaTriggerScriptMap;
-
- typedef UNORDERED_MAP<uint32, ReputationOnKillEntry> RepOnKillMap;
-
- typedef UNORDERED_MAP<uint32, WeatherZoneChances> WeatherZoneMap;
-
- typedef UNORDERED_MAP<uint32, PetCreateSpellEntry> PetCreateSpellMap;
-
- Player* GetPlayer(const char* name) const { return ObjectAccessor::Instance().FindPlayerByName(name);}
- Player* GetPlayer(uint64 guid) const { return ObjectAccessor::FindPlayer(guid); }
-
- static GameObjectInfo const *GetGameObjectInfo(uint32 id) { return sGOStorage.LookupEntry<GameObjectInfo>(id); }
-
- void LoadGameobjectInfo();
- void AddGameobjectInfo(GameObjectInfo *goinfo);
-
- Group * GetGroupByLeader(const uint64 &guid) const;
- void AddGroup(Group* group) { mGroupSet.insert( group ); }
- void RemoveGroup(Group* group) { mGroupSet.erase( group ); }
-
- Guild* GetGuildByLeader(uint64 const&guid) const;
- Guild* GetGuildById(const uint32 GuildId) const;
- Guild* GetGuildByName(std::string guildname) const;
- std::string GetGuildNameById(const uint32 GuildId) const;
- void AddGuild(Guild* guild) { mGuildSet.insert( guild ); }
- void RemoveGuild(Guild* guild) { mGuildSet.erase( guild ); }
-
- ArenaTeam* GetArenaTeamById(const uint32 ArenaTeamId) const;
- ArenaTeam* GetArenaTeamByName(std::string ArenaTeamName) const;
- ArenaTeam* GetArenaTeamByCapitan(uint64 const& guid) const;
- void AddArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.insert( arenateam ); }
- void RemoveArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.erase( arenateam ); }
- ArenaTeamSet::iterator GetArenaTeamSetBegin() { return mArenaTeamSet.begin(); }
- ArenaTeamSet::iterator GetArenaTeamSetEnd() { return mArenaTeamSet.end(); }
-
- static CreatureInfo const *GetCreatureTemplate( uint32 id );
- CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid );
- CreatureModelInfo const* GetCreatureModelRandomGender(uint32 display_id);
- uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data = NULL);
- EquipmentInfo const *GetEquipmentInfo( uint32 entry );
- static CreatureDataAddon const *GetCreatureAddon( uint32 lowguid )
- {
- return sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(lowguid);
- }
-
- static CreatureDataAddon const *GetCreatureTemplateAddon( uint32 entry )
- {
- return sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(entry);
- }
-
- static ItemPrototype const* GetItemPrototype(uint32 id) { return sItemStorage.LookupEntry<ItemPrototype>(id); }
-
- static InstanceTemplate const* GetInstanceTemplate(uint32 map)
- {
- return sInstanceTemplate.LookupEntry<InstanceTemplate>(map);
- }
-
- Item* GetAItem(uint32 id)
- {
- ItemMap::const_iterator itr = mAitems.find(id);
- if (itr != mAitems.end())
- {
- return itr->second;
- }
- return NULL;
- }
- void AddAItem(Item* it)
- {
- ASSERT( it );
- ASSERT( mAitems.find(it->GetGUIDLow()) == mAitems.end());
- mAitems[it->GetGUIDLow()] = it;
- }
- bool RemoveAItem(uint32 id)
- {
- ItemMap::iterator i = mAitems.find(id);
- if (i == mAitems.end())
- {
- return false;
- }
- mAitems.erase(i);
- return true;
- }
- AuctionHouseObject * GetAuctionsMap( uint32 location );
-
- //auction messages
- void SendAuctionWonMail( AuctionEntry * auction );
- void SendAuctionSalePendingMail( AuctionEntry * auction );
- void SendAuctionSuccessfulMail( AuctionEntry * auction );
- void SendAuctionExpiredMail( AuctionEntry * auction );
- static uint32 GetAuctionCut( uint32 location, uint32 highBid );
- static uint32 GetAuctionDeposit(uint32 location, uint32 time, Item *pItem);
- static uint32 GetAuctionOutBid(uint32 currentBid);
-
- PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const;
-
- PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const
- {
- if(class_ >= MAX_CLASSES) return NULL;
- return &playerClassInfo[class_];
- }
- void GetPlayerClassLevelInfo(uint32 class_,uint32 level, PlayerClassLevelInfo* info) const;
-
- PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const
- {
- if(race >= MAX_RACES) return NULL;
- if(class_ >= MAX_CLASSES) return NULL;
- PlayerInfo const* info = &playerInfo[race][class_];
- if(info->displayId_m==0 || info->displayId_f==0) return NULL;
- return info;
- }
- void GetPlayerLevelInfo(uint32 race, uint32 class_,uint32 level, PlayerLevelInfo* info) const;
-
- uint64 GetPlayerGUIDByName(std::string name) const;
- bool GetPlayerNameByGUID(const uint64 &guid, std::string &name) const;
- uint32 GetPlayerTeamByGUID(const uint64 &guid) const;
- uint32 GetPlayerAccountIdByGUID(const uint64 &guid) const;
- uint32 GetPlayerAccountIdByPlayerName(std::string name) const;
-
- uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid );
- void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost);
- uint16 GetTaxiMount( uint32 id, uint32 team );
- void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds );
- void GetTransportPathNodes( uint32 path, TransportPath &pathnodes );
-
- Quest const* GetQuestTemplate(uint32 quest_id) const
- {
- QuestMap::const_iterator itr = mQuestTemplates.find(quest_id);
- return itr != mQuestTemplates.end() ? itr->second : NULL;
- }
- QuestMap const& GetQuestTemplates() const { return mQuestTemplates; }
-
- uint32 GetQuestForAreaTrigger(uint32 Trigger_ID) const
- {
- QuestAreaTriggerMap::const_iterator itr = mQuestAreaTriggerMap.find(Trigger_ID);
- if(itr != mQuestAreaTriggerMap.end())
- return itr->second;
- return 0;
- }
- bool IsTavernAreaTrigger(uint32 Trigger_ID) const { return mTavernAreaTriggerSet.count(Trigger_ID) != 0; }
- bool IsGameObjectForQuests(uint32 entry) const { return mGameObjectForQuestSet.count(entry) != 0; }
- bool IsGuildVaultGameObject(Player *player, uint64 guid) const
- {
- if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
- if(go->GetGoType() == GAMEOBJECT_TYPE_GUILD_BANK)
- return true;
- return false;
- }
-
- uint32 GetBattleMasterBG(uint32 entry) const
- {
- BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
- if(itr != mBattleMastersMap.end())
- return itr->second;
- return 2; //BATTLEGROUND_WS - i will not add include only for constant usage!
- }
-
- void AddGossipText(GossipText *pGText);
- GossipText *GetGossipText(uint32 Text_ID);
-
- WorldSafeLocsEntry const *GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team);
- bool AddGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = true);
- void RemoveGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = false);
- void LoadGraveyardZones();
- GraveYardData const* FindGraveYardData(uint32 id, uint32 zone);
-
- AreaTrigger const* GetAreaTrigger(uint32 trigger) const
- {
- AreaTriggerMap::const_iterator itr = mAreaTriggers.find( trigger );
- if( itr != mAreaTriggers.end( ) )
- return &itr->second;
- return NULL;
- }
-
- AreaTrigger const* GetGoBackTrigger(uint32 Map) const;
-
- const char* GetAreaTriggerScriptName(uint32 id);
-
- ReputationOnKillEntry const* GetReputationOnKilEntry(uint32 id) const
- {
- RepOnKillMap::const_iterator itr = mRepOnKill.find(id);
- if(itr != mRepOnKill.end())
- return &itr->second;
- return NULL;
- }
-
- PetCreateSpellEntry const* GetPetCreateSpellEntry(uint32 id) const
- {
- PetCreateSpellMap::const_iterator itr = mPetCreateSpell.find(id);
- if(itr != mPetCreateSpell.end())
- return &itr->second;
- return NULL;
- }
-
- void LoadGuilds();
- void LoadArenaTeams();
- void LoadGroups();
- void LoadQuests();
- void LoadQuestRelations()
- {
- LoadGameobjectQuestRelations();
- LoadGameobjectInvolvedRelations();
- LoadCreatureQuestRelations();
- LoadCreatureInvolvedRelations();
- }
- void LoadGameobjectQuestRelations();
- void LoadGameobjectInvolvedRelations();
- void LoadCreatureQuestRelations();
- void LoadCreatureInvolvedRelations();
-
- QuestRelations mGOQuestRelations;
- QuestRelations mGOQuestInvolvedRelations;
- QuestRelations mCreatureQuestRelations;
- QuestRelations mCreatureQuestInvolvedRelations;
-
- void LoadGameObjectScripts();
- void LoadQuestEndScripts();
- void LoadQuestStartScripts();
- void LoadEventScripts();
- void LoadSpellScripts();
-
- bool LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value);
- bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",1,std::numeric_limits<int32>::max()); }
- void LoadPetCreateSpells();
- void LoadCreatureLocales();
- void LoadCreatureTemplates();
- void LoadCreatures();
- void LoadCreatureRespawnTimes();
- void LoadCreatureAddons();
- void LoadCreatureModelInfo();
- void LoadEquipmentTemplates();
- void LoadGameObjectLocales();
- void LoadGameobjects();
- void LoadGameobjectRespawnTimes();
- void LoadItemPrototypes();
- void LoadItemLocales();
- void LoadQuestLocales();
- void LoadNpcTextLocales();
- void LoadPageTextLocales();
- void LoadNpcOptionLocales();
- void LoadInstanceTemplate();
-
- void LoadGossipText();
-
- void LoadAreaTriggerTeleports();
- void LoadQuestAreaTriggers();
- void LoadAreaTriggerScripts();
- void LoadTavernAreaTriggers();
- void LoadBattleMastersEntry();
- void LoadGameObjectForQuests();
-
- void LoadItemTexts();
- void LoadPageTexts();
-
- //load first auction items, because of check if item exists, when loading
- void LoadAuctionItems();
- void LoadAuctions();
- void LoadPlayerInfo();
- void LoadPetLevelInfo();
- void LoadExplorationBaseXP();
- void LoadPetNames();
- void LoadPetNumber();
- void LoadCorpses();
- void LoadFishingBaseSkillLevel();
-
- void LoadReputationOnKill();
-
- void LoadWeatherZoneChances();
- void LoadGameTele();
-
- void LoadNpcOptions();
- void LoadNpcTextId();
- void LoadVendors();
- void LoadTrainerSpell();
-
- std::string GeneratePetName(uint32 entry);
- uint32 GetBaseXP(uint32 level);
-
- int32 GetFishingBaseSkillLevel(uint32 entry) const
- {
- FishingBaseSkillMap::const_iterator itr = mFishingBaseForArea.find(entry);
- return itr != mFishingBaseForArea.end() ? itr->second : 0;
- }
-
- void ReturnOrDeleteOldMails(bool serverUp);
-
- void SetHighestGuids();
- uint32 GenerateLowGuid(HighGuid guidhigh);
- uint32 GenerateAuctionID();
- uint32 GenerateMailID();
- uint32 GenerateItemTextID();
- uint32 GeneratePetNumber();
-
- void LoadPlayerInfoInCache();
- PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const;
- CachePlayerInfoMap m_mPlayerInfoMap;
-
- uint32 CreateItemText(std::string text);
- std::string GetItemText( uint32 id )
- {
- ItemTextMap::const_iterator itr = mItemTexts.find( id );
- if ( itr != mItemTexts.end() )
- return itr->second;
- else
- return "There is no info for this item";
- }
-
- typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
- ExclusiveQuestGroups mExclusiveQuestGroups;
-
- WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const
- {
- WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id);
- if(itr != mWeatherZoneMap.end())
- return &itr->second;
- else
- return NULL;
- }
-
- CellObjectGuids const& GetCellObjectGuids(uint16 mapid, uint8 spawnMode, uint32 cell_id)
- {
- return mMapObjectGuids[MAKE_PAIR32(mapid,spawnMode)][cell_id];
- }
-
- CreatureData const* GetCreatureData(uint32 guid) const
- {
- CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid);
- if(itr==mCreatureDataMap.end()) return NULL;
- return &itr->second;
- }
- CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
- void DeleteCreatureData(uint32 guid);
- CreatureLocale const* GetCreatureLocale(uint32 entry) const
- {
- CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
- if(itr==mCreatureLocaleMap.end()) return NULL;
- return &itr->second;
- }
- GameObjectLocale const* GetGameObjectLocale(uint32 entry) const
- {
- GameObjectLocaleMap::const_iterator itr = mGameObjectLocaleMap.find(entry);
- if(itr==mGameObjectLocaleMap.end()) return NULL;
- return &itr->second;
- }
- ItemLocale const* GetItemLocale(uint32 entry) const
- {
- ItemLocaleMap::const_iterator itr = mItemLocaleMap.find(entry);
- if(itr==mItemLocaleMap.end()) return NULL;
- return &itr->second;
- }
- QuestLocale const* GetQuestLocale(uint32 entry) const
- {
- QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry);
- if(itr==mQuestLocaleMap.end()) return NULL;
- return &itr->second;
- }
- NpcTextLocale const* GetNpcTextLocale(uint32 entry) const
- {
- NpcTextLocaleMap::const_iterator itr = mNpcTextLocaleMap.find(entry);
- if(itr==mNpcTextLocaleMap.end()) return NULL;
- return &itr->second;
- }
- PageTextLocale const* GetPageTextLocale(uint32 entry) const
- {
- PageTextLocaleMap::const_iterator itr = mPageTextLocaleMap.find(entry);
- if(itr==mPageTextLocaleMap.end()) return NULL;
- return &itr->second;
- }
-
- NpcOptionLocale const* GetNpcOptionLocale(uint32 entry) const
- {
- NpcOptionLocaleMap::const_iterator itr = mNpcOptionLocaleMap.find(entry);
- if(itr==mNpcOptionLocaleMap.end()) return NULL;
- return &itr->second;
- }
-
- GameObjectData const* GetGOData(uint32 guid) const
- {
- GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid);
- if(itr==mGameObjectDataMap.end()) return NULL;
- return &itr->second;
- }
- GameObjectData& NewGOData(uint32 guid) { return mGameObjectDataMap[guid]; }
- void DeleteGOData(uint32 guid);
-
- TrinityStringLocale const* GetTrinityStringLocale(int32 entry) const
- {
- TrinityStringLocaleMap::const_iterator itr = mTrinityStringLocaleMap.find(entry);
- if(itr==mTrinityStringLocaleMap.end()) return NULL;
- return &itr->second;
- }
- const char *GetTrinityString(int32 entry, int locale_idx) const;
- const char *GetTrinityStringForDBCLocale(int32 entry) const { return GetTrinityString(entry,DBCLocaleIndex); }
- int32 GetDBCLocaleIndex() const { return DBCLocaleIndex; }
- void SetDBCLocaleIndex(uint32 lang) { DBCLocaleIndex = GetIndexForLocale(LocaleConstant(lang)); }
-
- void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance);
- void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid);
-
- time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance) { return mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)]; }
- void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t);
- time_t GetGORespawnTime(uint32 loguid, uint32 instance) { return mGORespawnTimes[MAKE_PAIR64(loguid,instance)]; }
- void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t);
- void DeleteRespawnTimeForInstance(uint32 instance);
-
- // grid objects
- void AddCreatureToGrid(uint32 guid, CreatureData const* data);
- void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data);
- void AddGameobjectToGrid(uint32 guid, GameObjectData const* data);
- void RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data);
-
- // reserved names
- void LoadReservedPlayersNames();
- bool IsReservedName(std::string name) const
- {
- return m_ReservedNames.find(name) != m_ReservedNames.end();
- }
-
- // name with valid structure and symbols
- static bool IsValidName( std::string name, bool create = false );
- static bool IsValidCharterName( std::string name );
- static bool IsValidPetName( std::string name );
-
- static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names);
-
- void LoadSpellDisabledEntrys();
- bool IsPlayerSpellDisabled(uint32 spellid) { return (m_DisabledPlayerSpells.count(spellid) != 0); }
- bool IsCreatureSpellDisabled(uint32 spellid) { return (m_DisabledCreatureSpells.count(spellid) != 0); }
-
- int GetIndexForLocale(LocaleConstant loc);
- LocaleConstant GetLocaleForIndex(int i);
- // guild bank tabs
- const uint32 GetGuildBankTabPrice(uint8 Index) { return Index < GUILD_BANK_MAX_TABS ? mGuildBankTabPrice[Index] : 0; }
-
- uint16 GetConditionId(ConditionType condition, uint32 value1, uint32 value2);
- bool IsPlayerMeetToCondition(Player const* player, uint16 condition_id) const
- {
- if(condition_id >= mConditions.size())
- return false;
-
- return mConditions[condition_id].Meets(player);
- }
-
- GameTele const* GetGameTele(uint32 id) const
- {
- GameTeleMap::const_iterator itr = m_GameTeleMap.find(id);
- if(itr==m_GameTeleMap.end()) return NULL;
- return &itr->second;
- }
- GameTele const* GetGameTele(std::string name) const;
- GameTeleMap const& GetGameTeleMap() const { return m_GameTeleMap; }
- bool AddGameTele(GameTele& data);
- bool DeleteGameTele(std::string name);
-
- CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; }
-
- uint32 GetNpcGossip(uint32 entry) const
- {
- CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry);
- if(iter == m_mCacheNpcTextIdMap.end())
- return 0;
-
- return iter->second;
- }
-
- TrainerSpellData const* GetNpcTrainerSpells(uint32 entry) const
- {
- CacheTrainerSpellMap::const_iterator iter = m_mCacheTrainerSpellMap.find(entry);
- if(iter == m_mCacheTrainerSpellMap.end())
- return NULL;
-
- return &iter->second;
- }
-
- VendorItemData const* GetNpcVendorItemList(uint32 entry) const
- {
- CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry);
- if(iter == m_mCacheVendorItemMap.end())
- return NULL;
-
- return &iter->second;
- }
- void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true);
- bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true);
- bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
-
- protected:
- uint32 m_auctionid;
- uint32 m_mailid;
- uint32 m_ItemTextId;
-
- uint32 m_hiCharGuid;
- uint32 m_hiCreatureGuid;
- uint32 m_hiPetGuid;
- uint32 m_hiItemGuid;
- uint32 m_hiGoGuid;
- uint32 m_hiDoGuid;
- uint32 m_hiCorpseGuid;
-
- uint32 m_hiPetNumber;
-
- QuestMap mQuestTemplates;
-
- typedef UNORDERED_MAP<uint32, GossipText*> GossipTextMap;
- typedef UNORDERED_MAP<uint32, uint32> QuestAreaTriggerMap;
- typedef UNORDERED_MAP<uint32, uint32> BattleMastersMap;
- typedef UNORDERED_MAP<uint32, std::string> ItemTextMap;
- typedef std::set<uint32> TavernAreaTriggerSet;
- typedef std::set<uint32> GameObjectForQuestSet;
-
- GroupSet mGroupSet;
- GuildSet mGuildSet;
- ArenaTeamSet mArenaTeamSet;
-
- ItemMap mItems;
- ItemMap mAitems;
-
- ItemTextMap mItemTexts;
-
- AuctionHouseObject mHordeAuctions;
- AuctionHouseObject mAllianceAuctions;
- AuctionHouseObject mNeutralAuctions;
-
- QuestAreaTriggerMap mQuestAreaTriggerMap;
- BattleMastersMap mBattleMastersMap;
- TavernAreaTriggerSet mTavernAreaTriggerSet;
- GameObjectForQuestSet mGameObjectForQuestSet;
- GossipTextMap mGossipText;
- AreaTriggerMap mAreaTriggers;
- AreaTriggerScriptMap mAreaTriggerScripts;
-
- RepOnKillMap mRepOnKill;
-
- WeatherZoneMap mWeatherZoneMap;
-
- PetCreateSpellMap mPetCreateSpell;
-
- //character reserved names
- typedef std::set<std::string> ReservedNamesMap;
- ReservedNamesMap m_ReservedNames;
-
- std::set<uint32> m_DisabledPlayerSpells;
- std::set<uint32> m_DisabledCreatureSpells;
-
- GraveYardMap mGraveYardMap;
-
- GameTeleMap m_GameTeleMap;
-
- typedef std::vector<LocaleConstant> LocalForIndex;
- LocalForIndex m_LocalForIndex;
- int GetOrNewIndexForLocale(LocaleConstant loc);
-
- int DBCLocaleIndex;
- private:
- void LoadScripts(ScriptMapMap& scripts, char const* tablename);
- void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
- void LoadQuestRelationsHelper(QuestRelations& map,char const* table);
-
- typedef std::map<uint32,PetLevelInfo*> PetLevelInfoMap;
- // PetLevelInfoMap[creature_id][level]
- PetLevelInfoMap petInfo; // [creature_id][level]
-
- PlayerClassInfo playerClassInfo[MAX_CLASSES];
-
- void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const;
- PlayerInfo playerInfo[MAX_RACES][MAX_CLASSES];
-
- typedef std::map<uint32,uint32> BaseXPMap; // [area level][base xp]
- BaseXPMap mBaseXPTable;
-
- typedef std::map<uint32,int32> FishingBaseSkillMap; // [areaId][base skill level]
- FishingBaseSkillMap mFishingBaseForArea;
-
- typedef std::map<uint32,std::vector<std::string> > HalfNameMap;
- HalfNameMap PetHalfName0;
- HalfNameMap PetHalfName1;
-
- MapObjectGuids mMapObjectGuids;
- CreatureDataMap mCreatureDataMap;
- CreatureLocaleMap mCreatureLocaleMap;
- GameObjectDataMap mGameObjectDataMap;
- GameObjectLocaleMap mGameObjectLocaleMap;
- ItemLocaleMap mItemLocaleMap;
- QuestLocaleMap mQuestLocaleMap;
- NpcTextLocaleMap mNpcTextLocaleMap;
- PageTextLocaleMap mPageTextLocaleMap;
- TrinityStringLocaleMap mTrinityStringLocaleMap;
- NpcOptionLocaleMap mNpcOptionLocaleMap;
- RespawnTimes mCreatureRespawnTimes;
- RespawnTimes mGORespawnTimes;
-
- typedef std::vector<uint32> GuildBankTabPriceMap;
- GuildBankTabPriceMap mGuildBankTabPrice;
-
- // Storage for Conditions. First element (index 0) is reserved for zero-condition (nothing required)
- typedef std::vector<PlayerCondition> ConditionStore;
- ConditionStore mConditions;
-
- CacheNpcOptionList m_mCacheNpcOptionList;
- CacheNpcTextIdMap m_mCacheNpcTextIdMap;
- CacheVendorItemMap m_mCacheVendorItemMap;
- CacheTrainerSpellMap m_mCacheTrainerSpellMap;
-};
-
-#define objmgr Trinity::Singleton<ObjectMgr>::Instance()
-
-// scripting access functions
-bool TRINITY_DLL_SPEC LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits<int32>::min());
-TRINITY_DLL_SPEC const char* GetAreaTriggerScriptNameById(uint32 id);
-
-#endif
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _OBJECTMGR_H
+#define _OBJECTMGR_H
+
+#include "Log.h"
+#include "Object.h"
+#include "Bag.h"
+#include "Creature.h"
+#include "Player.h"
+#include "DynamicObject.h"
+#include "GameObject.h"
+#include "Corpse.h"
+#include "QuestDef.h"
+#include "Path.h"
+#include "ItemPrototype.h"
+#include "NPCHandler.h"
+#include "Database/DatabaseEnv.h"
+#include "AuctionHouseObject.h"
+#include "Mail.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "ObjectDefines.h"
+#include "Policies/Singleton.h"
+#include "Database/SQLStorage.h"
+
+#include <string>
+#include <map>
+#include <limits>
+
+extern SQLStorage sCreatureStorage;
+extern SQLStorage sCreatureDataAddonStorage;
+extern SQLStorage sCreatureInfoAddonStorage;
+extern SQLStorage sCreatureModelStorage;
+extern SQLStorage sEquipmentStorage;
+extern SQLStorage sGOStorage;
+extern SQLStorage sPageTextStore;
+extern SQLStorage sItemStorage;
+extern SQLStorage sInstanceTemplate;
+
+class Group;
+class Guild;
+class ArenaTeam;
+class Path;
+class TransportPath;
+class Item;
+
+struct GameTele
+{
+ float position_x;
+ float position_y;
+ float position_z;
+ float orientation;
+ uint32 mapId;
+ std::string name;
+ std::wstring wnameLow;
+};
+
+typedef UNORDERED_MAP<uint32, GameTele > GameTeleMap;
+typedef std::list<GossipOption> CacheNpcOptionList;
+
+struct ScriptInfo
+{
+ uint32 id;
+ uint32 delay;
+ uint32 command;
+ uint32 datalong;
+ uint32 datalong2;
+ int32 dataint;
+ float x;
+ float y;
+ float z;
+ float o;
+};
+
+typedef std::multimap<uint32, ScriptInfo> ScriptMap;
+typedef std::map<uint32, ScriptMap > ScriptMapMap;
+extern ScriptMapMap sQuestEndScripts;
+extern ScriptMapMap sQuestStartScripts;
+extern ScriptMapMap sSpellScripts;
+extern ScriptMapMap sGameObjectScripts;
+extern ScriptMapMap sEventScripts;
+
+struct AreaTrigger
+{
+ uint8 requiredLevel;
+ uint32 requiredItem;
+ uint32 requiredItem2;
+ uint32 heroicKey;
+ uint32 heroicKey2;
+ uint32 requiredQuest;
+ std::string requiredFailedText;
+ uint32 target_mapId;
+ float target_X;
+ float target_Y;
+ float target_Z;
+ float target_Orientation;
+};
+
+typedef std::set<uint32> CellGuidSet;
+typedef std::map<uint32/*player guid*/,uint32/*instance*/> CellCorpseSet;
+struct CellObjectGuids
+{
+ CellGuidSet creatures;
+ CellGuidSet gameobjects;
+ CellCorpseSet corpses;
+};
+typedef UNORDERED_MAP<uint32/*cell_id*/,CellObjectGuids> CellObjectGuidsMap;
+typedef UNORDERED_MAP<uint32/*(mapid,spawnMode) pair*/,CellObjectGuidsMap> MapObjectGuids;
+
+typedef UNORDERED_MAP<uint64/*(instance,guid) pair*/,time_t> RespawnTimes;
+
+
+// mangos string ranges
+#define MIN_TRINITY_STRING_ID 1
+#define MAX_TRINITY_STRING_ID 2000000000
+#define MIN_DB_SCRIPT_STRING_ID MAX_TRINITY_STRING_ID
+#define MAX_DB_SCRIPT_STRING_ID 2000010000
+
+struct TrinityStringLocale
+{
+ std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
+};
+
+typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
+typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
+typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
+typedef UNORDERED_MAP<uint32,GameObjectLocale> GameObjectLocaleMap;
+typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap;
+typedef UNORDERED_MAP<uint32,QuestLocale> QuestLocaleMap;
+typedef UNORDERED_MAP<uint32,NpcTextLocale> NpcTextLocaleMap;
+typedef UNORDERED_MAP<uint32,PageTextLocale> PageTextLocaleMap;
+typedef UNORDERED_MAP<uint32,TrinityStringLocale> TrinityStringLocaleMap;
+typedef UNORDERED_MAP<uint32,NpcOptionLocale> NpcOptionLocaleMap;
+
+typedef std::multimap<uint32,uint32> QuestRelations;
+
+struct PetLevelInfo
+{
+ PetLevelInfo() : health(0), mana(0) { for(int i=0; i < MAX_STATS; ++i ) stats[i] = 0; }
+
+ uint16 stats[MAX_STATS];
+ uint16 health;
+ uint16 mana;
+ uint16 armor;
+};
+
+struct ReputationOnKillEntry
+{
+ uint32 repfaction1;
+ uint32 repfaction2;
+ bool is_teamaward1;
+ uint32 reputation_max_cap1;
+ int32 repvalue1;
+ bool is_teamaward2;
+ uint32 reputation_max_cap2;
+ int32 repvalue2;
+ bool team_dependent;
+};
+
+struct PetCreateSpellEntry
+{
+ uint32 spellid[4];
+};
+
+#define WEATHER_SEASONS 4
+struct WeatherSeasonChances
+{
+ uint32 rainChance;
+ uint32 snowChance;
+ uint32 stormChance;
+};
+
+struct WeatherZoneChances
+{
+ WeatherSeasonChances data[WEATHER_SEASONS];
+};
+
+struct GraveYardData
+{
+ uint32 safeLocId;
+ uint32 team;
+};
+typedef std::multimap<uint32,GraveYardData> GraveYardMap;
+
+enum ConditionType
+{ // value1 value2 for the Condition enumed
+ CONDITION_NONE = 0, // 0 0
+ CONDITION_AURA = 1, // spell_id effindex
+ CONDITION_ITEM = 2, // item_id count
+ CONDITION_ITEM_EQUIPPED = 3, // item_id 0
+ CONDITION_ZONEID = 4, // zone_id 0
+ CONDITION_REPUTATION_RANK = 5, // faction_id min_rank
+ CONDITION_TEAM = 6, // player_team 0, (469 - Alliance 67 - Horde)
+ CONDITION_SKILL = 7, // skill_id skill_value
+ CONDITION_QUESTREWARDED = 8, // quest_id 0
+ CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active.
+ CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD ñommission aura active
+ CONDITION_NO_AURA = 11, // spell_id effindex
+ CONDITION_ACTIVE_EVENT = 12, // event_id
+};
+
+#define MAX_CONDITION 13 // maximum value in ConditionType enum
+
+//Player's info
+typedef struct _tagCachePlayerInfo
+{
+ std::string sPlayerName;
+ uint32 unfield;
+ uint32 unLevel;
+ uint8 unClass;
+//Arena
+ uint32 unArenaInfoId0;
+ uint32 unArenaInfoId1;
+ uint32 unArenaInfoId2;
+ uint32 unArenaInfoSlot0;
+ uint32 unArenaInfoSlot1;
+ uint32 unArenaInfoSlot2;
+}CachePlayerInfo, *PCachePlayerInfo;
+typedef UNORDERED_MAP<uint32, PCachePlayerInfo> CachePlayerInfoMap;
+
+struct PlayerCondition
+{
+ ConditionType condition; // additional condition type
+ uint32 value1; // data for the condition - see ConditionType definition
+ uint32 value2;
+
+ PlayerCondition(uint8 _condition = 0, uint32 _value1 = 0, uint32 _value2 = 0)
+ : condition(ConditionType(_condition)), value1(_value1), value2(_value2) {}
+
+ static bool IsValid(ConditionType condition, uint32 value1, uint32 value2);
+ // Checks correctness of values
+ bool Meets(Player const * APlayer) const; // Checks if the player meets the condition
+ bool operator == (PlayerCondition const& lc) const
+ {
+ return (lc.condition == condition && lc.value1 == value1 && lc.value2 == value2);
+ }
+};
+
+// NPC gossip text id
+typedef UNORDERED_MAP<uint32, uint32> CacheNpcTextIdMap;
+typedef std::list<GossipOption> CacheNpcOptionList;
+
+typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap;
+typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap;
+
+enum SkillRangeType
+{
+ SKILL_RANGE_LANGUAGE, // 300..300
+ SKILL_RANGE_LEVEL, // 1..max skill for level
+ SKILL_RANGE_MONO, // 1..1, grey monolite bar
+ SKILL_RANGE_RANK, // 1..skill for known rank
+ SKILL_RANGE_NONE, // 0..0 always
+};
+
+SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial);
+
+#define MAX_PLAYER_NAME 12 // max allowed by client name length
+#define MAX_INTERNAL_PLAYER_NAME 15 // max server internal player name length ( > MAX_PLAYER_NAME for support declined names )
+
+bool normalizePlayerName(std::string& name);
+
+struct TRINITY_DLL_SPEC LanguageDesc
+{
+ Language lang_id;
+ uint32 spell_id;
+ uint32 skill_id;
+};
+
+extern LanguageDesc lang_description[LANGUAGES_COUNT];
+TRINITY_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
+
+class PlayerDumpReader;
+
+class ObjectMgr
+{
+ friend class PlayerDumpReader;
+
+ public:
+ ObjectMgr();
+ ~ObjectMgr();
+
+ typedef UNORDERED_MAP<uint32, Item*> ItemMap;
+
+ typedef std::set< Group * > GroupSet;
+ typedef std::set< Guild * > GuildSet;
+ typedef std::set< ArenaTeam * > ArenaTeamSet;
+
+ typedef UNORDERED_MAP<uint32, Quest*> QuestMap;
+
+
+ typedef UNORDERED_MAP<uint32, AreaTrigger> AreaTriggerMap;
+
+ typedef UNORDERED_MAP<uint32, uint32> AreaTriggerScriptMap;
+
+ typedef UNORDERED_MAP<uint32, ReputationOnKillEntry> RepOnKillMap;
+
+ typedef UNORDERED_MAP<uint32, WeatherZoneChances> WeatherZoneMap;
+
+ typedef UNORDERED_MAP<uint32, PetCreateSpellEntry> PetCreateSpellMap;
+
+ typedef std::vector<std::string> ScriptNameMap;
+
+ Player* GetPlayer(const char* name) const { return ObjectAccessor::Instance().FindPlayerByName(name);}
+ Player* GetPlayer(uint64 guid) const { return ObjectAccessor::FindPlayer(guid); }
+
+ static GameObjectInfo const *GetGameObjectInfo(uint32 id) { return sGOStorage.LookupEntry<GameObjectInfo>(id); }
+
+ void LoadGameobjectInfo();
+ void AddGameobjectInfo(GameObjectInfo *goinfo);
+
+ Group * GetGroupByLeader(const uint64 &guid) const;
+ void AddGroup(Group* group) { mGroupSet.insert( group ); }
+ void RemoveGroup(Group* group) { mGroupSet.erase( group ); }
+
+ Guild* GetGuildByLeader(uint64 const&guid) const;
+ Guild* GetGuildById(const uint32 GuildId) const;
+ Guild* GetGuildByName(std::string guildname) const;
+ std::string GetGuildNameById(const uint32 GuildId) const;
+ void AddGuild(Guild* guild) { mGuildSet.insert( guild ); }
+ void RemoveGuild(Guild* guild) { mGuildSet.erase( guild ); }
+
+ ArenaTeam* GetArenaTeamById(const uint32 ArenaTeamId) const;
+ ArenaTeam* GetArenaTeamByName(std::string ArenaTeamName) const;
+ ArenaTeam* GetArenaTeamByCapitan(uint64 const& guid) const;
+ void AddArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.insert( arenateam ); }
+ void RemoveArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.erase( arenateam ); }
+ ArenaTeamSet::iterator GetArenaTeamSetBegin() { return mArenaTeamSet.begin(); }
+ ArenaTeamSet::iterator GetArenaTeamSetEnd() { return mArenaTeamSet.end(); }
+
+ static CreatureInfo const *GetCreatureTemplate( uint32 id );
+ CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid );
+ CreatureModelInfo const* GetCreatureModelRandomGender(uint32 display_id);
+ uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data = NULL);
+ EquipmentInfo const *GetEquipmentInfo( uint32 entry );
+ static CreatureDataAddon const *GetCreatureAddon( uint32 lowguid )
+ {
+ return sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(lowguid);
+ }
+
+ static CreatureDataAddon const *GetCreatureTemplateAddon( uint32 entry )
+ {
+ return sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(entry);
+ }
+
+ static ItemPrototype const* GetItemPrototype(uint32 id) { return sItemStorage.LookupEntry<ItemPrototype>(id); }
+
+ static InstanceTemplate const* GetInstanceTemplate(uint32 map)
+ {
+ return sInstanceTemplate.LookupEntry<InstanceTemplate>(map);
+ }
+
+ Item* GetAItem(uint32 id)
+ {
+ ItemMap::const_iterator itr = mAitems.find(id);
+ if (itr != mAitems.end())
+ {
+ return itr->second;
+ }
+ return NULL;
+ }
+ void AddAItem(Item* it)
+ {
+ ASSERT( it );
+ ASSERT( mAitems.find(it->GetGUIDLow()) == mAitems.end());
+ mAitems[it->GetGUIDLow()] = it;
+ }
+ bool RemoveAItem(uint32 id)
+ {
+ ItemMap::iterator i = mAitems.find(id);
+ if (i == mAitems.end())
+ {
+ return false;
+ }
+ mAitems.erase(i);
+ return true;
+ }
+ AuctionHouseObject * GetAuctionsMap( uint32 location );
+
+ //auction messages
+ void SendAuctionWonMail( AuctionEntry * auction );
+ void SendAuctionSalePendingMail( AuctionEntry * auction );
+ void SendAuctionSuccessfulMail( AuctionEntry * auction );
+ void SendAuctionExpiredMail( AuctionEntry * auction );
+ static uint32 GetAuctionCut( uint32 location, uint32 highBid );
+ static uint32 GetAuctionDeposit(uint32 location, uint32 time, Item *pItem);
+ static uint32 GetAuctionOutBid(uint32 currentBid);
+
+ PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const;
+
+ PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const
+ {
+ if(class_ >= MAX_CLASSES) return NULL;
+ return &playerClassInfo[class_];
+ }
+ void GetPlayerClassLevelInfo(uint32 class_,uint32 level, PlayerClassLevelInfo* info) const;
+
+ PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const
+ {
+ if(race >= MAX_RACES) return NULL;
+ if(class_ >= MAX_CLASSES) return NULL;
+ PlayerInfo const* info = &playerInfo[race][class_];
+ if(info->displayId_m==0 || info->displayId_f==0) return NULL;
+ return info;
+ }
+ void GetPlayerLevelInfo(uint32 race, uint32 class_,uint32 level, PlayerLevelInfo* info) const;
+
+ uint64 GetPlayerGUIDByName(std::string name) const;
+ bool GetPlayerNameByGUID(const uint64 &guid, std::string &name) const;
+ uint32 GetPlayerTeamByGUID(const uint64 &guid) const;
+ uint32 GetPlayerAccountIdByGUID(const uint64 &guid) const;
+ uint32 GetPlayerAccountIdByPlayerName(std::string name) const;
+
+ uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid );
+ void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost);
+ uint16 GetTaxiMount( uint32 id, uint32 team );
+ void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds );
+ void GetTransportPathNodes( uint32 path, TransportPath &pathnodes );
+
+ Quest const* GetQuestTemplate(uint32 quest_id) const
+ {
+ QuestMap::const_iterator itr = mQuestTemplates.find(quest_id);
+ return itr != mQuestTemplates.end() ? itr->second : NULL;
+ }
+ QuestMap const& GetQuestTemplates() const { return mQuestTemplates; }
+
+ uint32 GetQuestForAreaTrigger(uint32 Trigger_ID) const
+ {
+ QuestAreaTriggerMap::const_iterator itr = mQuestAreaTriggerMap.find(Trigger_ID);
+ if(itr != mQuestAreaTriggerMap.end())
+ return itr->second;
+ return 0;
+ }
+ bool IsTavernAreaTrigger(uint32 Trigger_ID) const { return mTavernAreaTriggerSet.count(Trigger_ID) != 0; }
+ bool IsGameObjectForQuests(uint32 entry) const { return mGameObjectForQuestSet.count(entry) != 0; }
+ bool IsGuildVaultGameObject(Player *player, uint64 guid) const
+ {
+ if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
+ if(go->GetGoType() == GAMEOBJECT_TYPE_GUILD_BANK)
+ return true;
+ return false;
+ }
+
+ uint32 GetBattleMasterBG(uint32 entry) const
+ {
+ BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
+ if(itr != mBattleMastersMap.end())
+ return itr->second;
+ return 2; //BATTLEGROUND_WS - i will not add include only for constant usage!
+ }
+
+ void AddGossipText(GossipText *pGText);
+ GossipText *GetGossipText(uint32 Text_ID);
+
+ WorldSafeLocsEntry const *GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team);
+ bool AddGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = true);
+ void RemoveGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = false);
+ void LoadGraveyardZones();
+ GraveYardData const* FindGraveYardData(uint32 id, uint32 zone);
+
+ AreaTrigger const* GetAreaTrigger(uint32 trigger) const
+ {
+ AreaTriggerMap::const_iterator itr = mAreaTriggers.find( trigger );
+ if( itr != mAreaTriggers.end( ) )
+ return &itr->second;
+ return NULL;
+ }
+
+ AreaTrigger const* GetGoBackTrigger(uint32 Map) const;
+
+ uint32 GetAreaTriggerScriptId(uint32 trigger_id);
+
+ ReputationOnKillEntry const* GetReputationOnKilEntry(uint32 id) const
+ {
+ RepOnKillMap::const_iterator itr = mRepOnKill.find(id);
+ if(itr != mRepOnKill.end())
+ return &itr->second;
+ return NULL;
+ }
+
+ PetCreateSpellEntry const* GetPetCreateSpellEntry(uint32 id) const
+ {
+ PetCreateSpellMap::const_iterator itr = mPetCreateSpell.find(id);
+ if(itr != mPetCreateSpell.end())
+ return &itr->second;
+ return NULL;
+ }
+
+ void LoadGuilds();
+ void LoadArenaTeams();
+ void LoadGroups();
+ void LoadQuests();
+ void LoadQuestRelations()
+ {
+ LoadGameobjectQuestRelations();
+ LoadGameobjectInvolvedRelations();
+ LoadCreatureQuestRelations();
+ LoadCreatureInvolvedRelations();
+ }
+ void LoadGameobjectQuestRelations();
+ void LoadGameobjectInvolvedRelations();
+ void LoadCreatureQuestRelations();
+ void LoadCreatureInvolvedRelations();
+
+ QuestRelations mGOQuestRelations;
+ QuestRelations mGOQuestInvolvedRelations;
+ QuestRelations mCreatureQuestRelations;
+ QuestRelations mCreatureQuestInvolvedRelations;
+
+ void LoadGameObjectScripts();
+ void LoadQuestEndScripts();
+ void LoadQuestStartScripts();
+ void LoadEventScripts();
+ void LoadSpellScripts();
+
+ bool LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value);
+ bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",MIN_TRINITY_STRING_ID,MAX_TRINITY_STRING_ID); }
+ void LoadDbScriptStrings();
+ void LoadPetCreateSpells();
+ void LoadCreatureLocales();
+ void LoadCreatureTemplates();
+ void LoadCreatures();
+ void LoadCreatureRespawnTimes();
+ void LoadCreatureAddons();
+ void LoadCreatureModelInfo();
+ void LoadEquipmentTemplates();
+ void LoadGameObjectLocales();
+ void LoadGameobjects();
+ void LoadGameobjectRespawnTimes();
+ void LoadItemPrototypes();
+ void LoadItemLocales();
+ void LoadQuestLocales();
+ void LoadNpcTextLocales();
+ void LoadPageTextLocales();
+ void LoadNpcOptionLocales();
+ void LoadInstanceTemplate();
+
+ void LoadGossipText();
+
+ void LoadAreaTriggerTeleports();
+ void LoadQuestAreaTriggers();
+ void LoadAreaTriggerScripts();
+ void LoadTavernAreaTriggers();
+ void LoadBattleMastersEntry();
+ void LoadGameObjectForQuests();
+
+ void LoadItemTexts();
+ void LoadPageTexts();
+
+ //load first auction items, because of check if item exists, when loading
+ void LoadAuctionItems();
+ void LoadAuctions();
+ void LoadPlayerInfo();
+ void LoadPetLevelInfo();
+ void LoadExplorationBaseXP();
+ void LoadPetNames();
+ void LoadPetNumber();
+ void LoadCorpses();
+ void LoadFishingBaseSkillLevel();
+
+ void LoadReputationOnKill();
+
+ void LoadWeatherZoneChances();
+ void LoadGameTele();
+
+ void LoadNpcOptions();
+ void LoadNpcTextId();
+ void LoadVendors();
+ void LoadTrainerSpell();
+
+ std::string GeneratePetName(uint32 entry);
+ uint32 GetBaseXP(uint32 level);
+
+ int32 GetFishingBaseSkillLevel(uint32 entry) const
+ {
+ FishingBaseSkillMap::const_iterator itr = mFishingBaseForArea.find(entry);
+ return itr != mFishingBaseForArea.end() ? itr->second : 0;
+ }
+
+ void ReturnOrDeleteOldMails(bool serverUp);
+
+ void SetHighestGuids();
+ uint32 GenerateLowGuid(HighGuid guidhigh);
+ uint32 GenerateAuctionID();
+ uint32 GenerateMailID();
+ uint32 GenerateItemTextID();
+ uint32 GeneratePetNumber();
+ uint32 GenerateArenaTeamId();
+ uint32 GenerateGuildId();
+
+ void LoadPlayerInfoInCache();
+ PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const;
+ CachePlayerInfoMap m_mPlayerInfoMap;
+
+ uint32 CreateItemText(std::string text);
+ std::string GetItemText( uint32 id )
+ {
+ ItemTextMap::const_iterator itr = mItemTexts.find( id );
+ if ( itr != mItemTexts.end() )
+ return itr->second;
+ else
+ return "There is no info for this item";
+ }
+
+ typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
+ ExclusiveQuestGroups mExclusiveQuestGroups;
+
+ WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const
+ {
+ WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id);
+ if(itr != mWeatherZoneMap.end())
+ return &itr->second;
+ else
+ return NULL;
+ }
+
+ CellObjectGuids const& GetCellObjectGuids(uint16 mapid, uint8 spawnMode, uint32 cell_id)
+ {
+ return mMapObjectGuids[MAKE_PAIR32(mapid,spawnMode)][cell_id];
+ }
+
+ CreatureData const* GetCreatureData(uint32 guid) const
+ {
+ CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid);
+ if(itr==mCreatureDataMap.end()) return NULL;
+ return &itr->second;
+ }
+ CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
+ void DeleteCreatureData(uint32 guid);
+ CreatureLocale const* GetCreatureLocale(uint32 entry) const
+ {
+ CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
+ if(itr==mCreatureLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ GameObjectLocale const* GetGameObjectLocale(uint32 entry) const
+ {
+ GameObjectLocaleMap::const_iterator itr = mGameObjectLocaleMap.find(entry);
+ if(itr==mGameObjectLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ ItemLocale const* GetItemLocale(uint32 entry) const
+ {
+ ItemLocaleMap::const_iterator itr = mItemLocaleMap.find(entry);
+ if(itr==mItemLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ QuestLocale const* GetQuestLocale(uint32 entry) const
+ {
+ QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry);
+ if(itr==mQuestLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ NpcTextLocale const* GetNpcTextLocale(uint32 entry) const
+ {
+ NpcTextLocaleMap::const_iterator itr = mNpcTextLocaleMap.find(entry);
+ if(itr==mNpcTextLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ PageTextLocale const* GetPageTextLocale(uint32 entry) const
+ {
+ PageTextLocaleMap::const_iterator itr = mPageTextLocaleMap.find(entry);
+ if(itr==mPageTextLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ NpcOptionLocale const* GetNpcOptionLocale(uint32 entry) const
+ {
+ NpcOptionLocaleMap::const_iterator itr = mNpcOptionLocaleMap.find(entry);
+ if(itr==mNpcOptionLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+
+ GameObjectData const* GetGOData(uint32 guid) const
+ {
+ GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid);
+ if(itr==mGameObjectDataMap.end()) return NULL;
+ return &itr->second;
+ }
+ GameObjectData& NewGOData(uint32 guid) { return mGameObjectDataMap[guid]; }
+ void DeleteGOData(uint32 guid);
+
+ TrinityStringLocale const* GetTrinityStringLocale(int32 entry) const
+ {
+ TrinityStringLocaleMap::const_iterator itr = mTrinityStringLocaleMap.find(entry);
+ if(itr==mTrinityStringLocaleMap.end()) return NULL;
+ return &itr->second;
+ }
+ const char *GetTrinityString(int32 entry, int locale_idx) const;
+ const char *GetTrinityStringForDBCLocale(int32 entry) const { return GetTrinityString(entry,DBCLocaleIndex); }
+ int32 GetDBCLocaleIndex() const { return DBCLocaleIndex; }
+ void SetDBCLocaleIndex(uint32 lang) { DBCLocaleIndex = GetIndexForLocale(LocaleConstant(lang)); }
+
+ void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance);
+ void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid);
+
+ time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance) { return mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)]; }
+ void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t);
+ time_t GetGORespawnTime(uint32 loguid, uint32 instance) { return mGORespawnTimes[MAKE_PAIR64(loguid,instance)]; }
+ void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t);
+ void DeleteRespawnTimeForInstance(uint32 instance);
+
+ // grid objects
+ void AddCreatureToGrid(uint32 guid, CreatureData const* data);
+ void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data);
+ void AddGameobjectToGrid(uint32 guid, GameObjectData const* data);
+ void RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data);
+
+ // reserved names
+ void LoadReservedPlayersNames();
+ bool IsReservedName(std::string name) const
+ {
+ return m_ReservedNames.find(name) != m_ReservedNames.end();
+ }
+
+ // name with valid structure and symbols
+ static bool IsValidName( std::string name, bool create = false );
+ static bool IsValidCharterName( std::string name );
+ static bool IsValidPetName( std::string name );
+
+ static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names);
+
+ void LoadSpellDisabledEntrys();
+ bool IsPlayerSpellDisabled(uint32 spellid) { return (m_DisabledPlayerSpells.count(spellid) != 0); }
+ bool IsCreatureSpellDisabled(uint32 spellid) { return (m_DisabledCreatureSpells.count(spellid) != 0); }
+
+ int GetIndexForLocale(LocaleConstant loc);
+ LocaleConstant GetLocaleForIndex(int i);
+ // guild bank tabs
+ uint32 GetGuildBankTabPrice(uint8 Index) const { return Index < GUILD_BANK_MAX_TABS ? mGuildBankTabPrice[Index] : 0; }
+
+ uint16 GetConditionId(ConditionType condition, uint32 value1, uint32 value2);
+ bool IsPlayerMeetToCondition(Player const* player, uint16 condition_id) const
+ {
+ if(condition_id >= mConditions.size())
+ return false;
+
+ return mConditions[condition_id].Meets(player);
+ }
+
+ GameTele const* GetGameTele(uint32 id) const
+ {
+ GameTeleMap::const_iterator itr = m_GameTeleMap.find(id);
+ if(itr==m_GameTeleMap.end()) return NULL;
+ return &itr->second;
+ }
+ GameTele const* GetGameTele(std::string name) const;
+ GameTeleMap const& GetGameTeleMap() const { return m_GameTeleMap; }
+ bool AddGameTele(GameTele& data);
+ bool DeleteGameTele(std::string name);
+
+ CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; }
+
+ uint32 GetNpcGossip(uint32 entry) const
+ {
+ CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry);
+ if(iter == m_mCacheNpcTextIdMap.end())
+ return 0;
+
+ return iter->second;
+ }
+
+ TrainerSpellData const* GetNpcTrainerSpells(uint32 entry) const
+ {
+ CacheTrainerSpellMap::const_iterator iter = m_mCacheTrainerSpellMap.find(entry);
+ if(iter == m_mCacheTrainerSpellMap.end())
+ return NULL;
+
+ return &iter->second;
+ }
+
+ VendorItemData const* GetNpcVendorItemList(uint32 entry) const
+ {
+ CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry);
+ if(iter == m_mCacheVendorItemMap.end())
+ return NULL;
+
+ return &iter->second;
+ }
+ void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true); // for event
+ bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event
+ bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const;
+
+ void LoadScriptNames();
+ ScriptNameMap &GetScriptNames() { return m_scriptNames; }
+ const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; }
+ uint32 GetScriptId(const char *name);
+ protected:
+
+ // first free id for selected id type
+ uint32 m_auctionid;
+ uint32 m_mailid;
+ uint32 m_ItemTextId;
+ uint32 m_arenaTeamId;
+ uint32 m_guildId;
+ uint32 m_hiPetNumber;
+
+ // first free low guid for seelcted guid type
+ uint32 m_hiCharGuid;
+ uint32 m_hiCreatureGuid;
+ uint32 m_hiPetGuid;
+ uint32 m_hiItemGuid;
+ uint32 m_hiGoGuid;
+ uint32 m_hiDoGuid;
+ uint32 m_hiCorpseGuid;
+
+ QuestMap mQuestTemplates;
+
+ typedef UNORDERED_MAP<uint32, GossipText*> GossipTextMap;
+ typedef UNORDERED_MAP<uint32, uint32> QuestAreaTriggerMap;
+ typedef UNORDERED_MAP<uint32, uint32> BattleMastersMap;
+ typedef UNORDERED_MAP<uint32, std::string> ItemTextMap;
+ typedef std::set<uint32> TavernAreaTriggerSet;
+ typedef std::set<uint32> GameObjectForQuestSet;
+
+ GroupSet mGroupSet;
+ GuildSet mGuildSet;
+ ArenaTeamSet mArenaTeamSet;
+
+ ItemMap mItems;
+ ItemMap mAitems;
+
+ ItemTextMap mItemTexts;
+
+ AuctionHouseObject mHordeAuctions;
+ AuctionHouseObject mAllianceAuctions;
+ AuctionHouseObject mNeutralAuctions;
+
+ QuestAreaTriggerMap mQuestAreaTriggerMap;
+ BattleMastersMap mBattleMastersMap;
+ TavernAreaTriggerSet mTavernAreaTriggerSet;
+ GameObjectForQuestSet mGameObjectForQuestSet;
+ GossipTextMap mGossipText;
+ AreaTriggerMap mAreaTriggers;
+ AreaTriggerScriptMap mAreaTriggerScripts;
+
+ RepOnKillMap mRepOnKill;
+
+ WeatherZoneMap mWeatherZoneMap;
+
+ PetCreateSpellMap mPetCreateSpell;
+
+ //character reserved names
+ typedef std::set<std::string> ReservedNamesMap;
+ ReservedNamesMap m_ReservedNames;
+
+ std::set<uint32> m_DisabledPlayerSpells;
+ std::set<uint32> m_DisabledCreatureSpells;
+
+ GraveYardMap mGraveYardMap;
+
+ GameTeleMap m_GameTeleMap;
+
+ ScriptNameMap m_scriptNames;
+
+ typedef std::vector<LocaleConstant> LocalForIndex;
+ LocalForIndex m_LocalForIndex;
+ int GetOrNewIndexForLocale(LocaleConstant loc);
+
+ int DBCLocaleIndex;
+ private:
+ void LoadScripts(ScriptMapMap& scripts, char const* tablename);
+ void CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids);
+ void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
+ void LoadQuestRelationsHelper(QuestRelations& map,char const* table);
+
+ typedef std::map<uint32,PetLevelInfo*> PetLevelInfoMap;
+ // PetLevelInfoMap[creature_id][level]
+ PetLevelInfoMap petInfo; // [creature_id][level]
+
+ PlayerClassInfo playerClassInfo[MAX_CLASSES];
+
+ void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const;
+ PlayerInfo playerInfo[MAX_RACES][MAX_CLASSES];
+
+ typedef std::map<uint32,uint32> BaseXPMap; // [area level][base xp]
+ BaseXPMap mBaseXPTable;
+
+ typedef std::map<uint32,int32> FishingBaseSkillMap; // [areaId][base skill level]
+ FishingBaseSkillMap mFishingBaseForArea;
+
+ typedef std::map<uint32,std::vector<std::string> > HalfNameMap;
+ HalfNameMap PetHalfName0;
+ HalfNameMap PetHalfName1;
+
+ MapObjectGuids mMapObjectGuids;
+ CreatureDataMap mCreatureDataMap;
+ CreatureLocaleMap mCreatureLocaleMap;
+ GameObjectDataMap mGameObjectDataMap;
+ GameObjectLocaleMap mGameObjectLocaleMap;
+ ItemLocaleMap mItemLocaleMap;
+ QuestLocaleMap mQuestLocaleMap;
+ NpcTextLocaleMap mNpcTextLocaleMap;
+ PageTextLocaleMap mPageTextLocaleMap;
+ TrinityStringLocaleMap mTrinityStringLocaleMap;
+ NpcOptionLocaleMap mNpcOptionLocaleMap;
+ RespawnTimes mCreatureRespawnTimes;
+ RespawnTimes mGORespawnTimes;
+
+ typedef std::vector<uint32> GuildBankTabPriceMap;
+ GuildBankTabPriceMap mGuildBankTabPrice;
+
+ // Storage for Conditions. First element (index 0) is reserved for zero-condition (nothing required)
+ typedef std::vector<PlayerCondition> ConditionStore;
+ ConditionStore mConditions;
+
+ CacheNpcOptionList m_mCacheNpcOptionList;
+ CacheNpcTextIdMap m_mCacheNpcTextIdMap;
+ CacheVendorItemMap m_mCacheVendorItemMap;
+ CacheTrainerSpellMap m_mCacheTrainerSpellMap;
+};
+
+#define objmgr Trinity::Singleton<ObjectMgr>::Instance()
+
+// scripting access functions
+TRINITY_DLL_SPEC bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits<int32>::min());
+TRINITY_DLL_SPEC uint32 GetAreaTriggerScriptId(uint32 trigger_id);
+TRINITY_DLL_SPEC uint32 GetScriptId(const char *name);
+TRINITY_DLL_SPEC ObjectMgr::ScriptNameMap& GetScriptNames();
+
+#endif
diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp
index 78f90bc9c9e..cd14d603e92 100644
--- a/src/game/PlayerDump.cpp
+++ b/src/game/PlayerDump.cpp
@@ -1,634 +1,631 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "Common.h"
-#include "PlayerDump.h"
-#include "Database/DatabaseEnv.h"
-#include "Database/SQLStorage.h"
-#include "UpdateFields.h"
-#include "ObjectMgr.h"
-
-// Character Dump tables
-#define DUMP_TABLE_COUNT 19
-
-struct DumpTable
-{
- char const* name;
- DumpTableType type;
-};
-
-static DumpTable dumpTables[DUMP_TABLE_COUNT] =
-{
- { "characters", DTT_CHARACTER },
- { "character_queststatus", DTT_CHAR_TABLE },
- { "character_reputation", DTT_CHAR_TABLE },
- { "character_spell", DTT_CHAR_TABLE },
- { "character_spell_cooldown", DTT_CHAR_TABLE },
- { "character_action", DTT_CHAR_TABLE },
- { "character_aura", DTT_CHAR_TABLE },
- { "character_homebind", DTT_CHAR_TABLE },
- { "character_ticket", DTT_CHAR_TABLE },
- { "character_inventory", DTT_INVENTORY },
- { "mail", DTT_MAIL },
- { "mail_items", DTT_MAIL_ITEM },
- { "item_instance", DTT_ITEM },
- { "character_gifts", DTT_ITEM_GIFT },
- { "item_text", DTT_ITEM_TEXT },
- { "character_pet", DTT_PET },
- { "pet_aura", DTT_PET_TABLE },
- { "pet_spell", DTT_PET_TABLE },
- { "pet_spell_cooldown", DTT_PET_TABLE },
-};
-
-// Low level functions
-static bool findtoknth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e)
-{
- int i; s = e = 0;
- std::string::size_type size = str.size();
- for(i = 1; s < size && i < n; s++) if(str[s] == ' ') ++i;
- if (i < n)
- return false;
-
- e = str.find(' ', s);
-
- return e != std::string::npos;
-}
-
-std::string gettoknth(std::string &str, int n)
-{
- std::string::size_type s = 0, e = 0;
- if(!findtoknth(str, n, s, e))
- return "";
-
- return str.substr(s, e-s);
-}
-
-bool findnth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e)
-{
- s = str.find("VALUES ('")+9;
- if (s == std::string::npos) return false;
-
- do
- {
- e = str.find("'",s);
- if (e == std::string::npos) return false;
- } while(str[e-1] == '\\');
-
- for(int i = 1; i < n; i++)
- {
- do
- {
- s = e+4;
- e = str.find("'",s);
- if (e == std::string::npos) return false;
- } while (str[e-1] == '\\');
- }
- return true;
-}
-
-std::string gettablename(std::string &str)
-{
- std::string::size_type s = 13;
- std::string::size_type e = str.find(_TABLE_SIM_, s);
- if (e == std::string::npos)
- return "";
-
- return str.substr(s, e-s);
-}
-
-bool changenth(std::string &str, int n, const char *with, bool insert = false, bool nonzero = false)
-{
- std::string::size_type s, e;
- if(!findnth(str,n,s,e))
- return false;
-
- if(nonzero && str.substr(s,e-s) == "0")
- return true; // not an error
- if(!insert)
- str.replace(s,e-s, with);
- else
- str.insert(s, with);
-
- return true;
-}
-
-std::string getnth(std::string &str, int n)
-{
- std::string::size_type s, e;
- if(!findnth(str,n,s,e))
- return "";
-
- return str.substr(s, e-s);
-}
-
-bool changetoknth(std::string &str, int n, const char *with, bool insert = false, bool nonzero = false)
-{
- std::string::size_type s = 0, e = 0;
- if(!findtoknth(str, n, s, e))
- return false;
- if(nonzero && str.substr(s,e-s) == "0")
- return true; // not an error
- if(!insert)
- str.replace(s, e-s, with);
- else
- str.insert(s, with);
-
- return true;
-}
-
-uint32 registerNewGuid(uint32 oldGuid, std::map<uint32, uint32> &guidMap, uint32 hiGuid)
-{
- std::map<uint32, uint32>::iterator itr = guidMap.find(oldGuid);
- if(itr != guidMap.end())
- return itr->second;
-
- uint32 newguid = hiGuid + guidMap.size();
- guidMap[oldGuid] = newguid;
- return newguid;
-}
-
-bool changeGuid(std::string &str, int n, std::map<uint32, uint32> &guidMap, uint32 hiGuid, bool nonzero = false)
-{
- char chritem[20];
- uint32 oldGuid = atoi(getnth(str, n).c_str());
- if (nonzero && oldGuid == 0)
- return true; // not an error
-
- uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid);
- snprintf(chritem, 20, "%d", newGuid);
-
- return changenth(str, n, chritem, false, nonzero);
-}
-
-bool changetokGuid(std::string &str, int n, std::map<uint32, uint32> &guidMap, uint32 hiGuid, bool nonzero = false)
-{
- char chritem[20];
- uint32 oldGuid = atoi(gettoknth(str, n).c_str());
- if (nonzero && oldGuid == 0)
- return true; // not an error
-
- uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid);
- snprintf(chritem, 20, "%d", newGuid);
-
- return changetoknth(str, n, chritem, false, nonzero);
-}
-
-std::string CreateDumpString(char const* tableName, QueryResult *result)
-{
- if(!tableName || !result) return "";
- std::ostringstream ss;
- ss << "INSERT INTO "<< _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES (";
- Field *fields = result->Fetch();
- for(uint32 i = 0; i < result->GetFieldCount(); i++)
- {
- if (i == 0) ss << "'";
- else ss << ", '";
-
- std::string s = fields[i].GetCppString();
- CharacterDatabase.escape_string(s);
- ss << s;
-
- ss << "'";
- }
- ss << ");";
- return ss.str();
-}
-
-std::string PlayerDumpWriter::GenerateWhereStr(char const* field, uint32 guid)
-{
- std::ostringstream wherestr;
- wherestr << field << " = '" << guid << "'";
- return wherestr.str();
-}
-
-std::string PlayerDumpWriter::GenerateWhereStr(char const* field, GUIDs const& guids, GUIDs::const_iterator& itr)
-{
- std::ostringstream wherestr;
- wherestr << field << " IN ('";
- for(; itr != guids.end(); ++itr)
- {
- wherestr << *itr;
-
- if(wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query
- {
- ++itr;
- break;
- }
-
- GUIDs::const_iterator itr2 = itr;
- if(++itr2 != guids.end())
- wherestr << "','";
- }
- wherestr << "')";
- return wherestr.str();
-}
-
-void StoreGUID(QueryResult *result,uint32 field,std::set<uint32>& guids)
-{
- Field* fields = result->Fetch();
- uint32 guid = fields[field].GetUInt32();
- if(guid)
- guids.insert(guid);
-}
-
-void StoreGUID(QueryResult *result,uint32 data,uint32 field, std::set<uint32>& guids)
-{
- Field* fields = result->Fetch();
- std::string dataStr = fields[data].GetCppString();
- uint32 guid = atoi(gettoknth(dataStr, field).c_str());
- if(guid)
- guids.insert(guid);
-}
-
-// Writing - High-level functions
-void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type)
-{
- GUIDs const* guids = NULL;
- char const* fieldname = NULL;
-
- switch ( type )
- {
- case DTT_ITEM: fieldname = "guid"; guids = &items; break;
- case DTT_ITEM_GIFT: fieldname = "item_guid"; guids = &items; break;
- case DTT_PET: fieldname = "owner"; break;
- case DTT_PET_TABLE: fieldname = "guid"; guids = &pets; break;
- case DTT_MAIL: fieldname = "receiver"; break;
- case DTT_MAIL_ITEM: fieldname = "mail_id"; guids = &mails; break;
- case DTT_ITEM_TEXT: fieldname = "id"; guids = &texts; break;
- default: fieldname = "guid"; break;
- }
-
- // for guid set stop if set is empty
- if(guids && guids->empty())
- return; // nothing to do
-
- // setup for guids case start position
- GUIDs::const_iterator guids_itr;
- if(guids)
- guids_itr = guids->begin();
-
- do
- {
- std::string wherestr;
-
- if(guids) // set case, get next guids string
- wherestr = GenerateWhereStr(fieldname,*guids,guids_itr);
- else // not set case, get single guid string
- wherestr = GenerateWhereStr(fieldname,guid);
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str());
- if(!result)
- return;
-
- do
- {
- // collect guids
- switch ( type )
- {
- case DTT_INVENTORY:
- StoreGUID(result,3,items); break; // item guid collection
- case DTT_ITEM:
- StoreGUID(result,0,ITEM_FIELD_ITEM_TEXT_ID,texts); break;
- // item text id collection
- case DTT_PET:
- StoreGUID(result,0,pets); break; // pet guid collection
- case DTT_MAIL:
- StoreGUID(result,0,mails); // mail id collection
- StoreGUID(result,6,texts); break; // item text id collection
- case DTT_MAIL_ITEM:
- StoreGUID(result,1,items); break; // item guid collection
- default: break;
- }
-
- dump += CreateDumpString(tableTo, result);
- dump += "\n";
- }
- while (result->NextRow());
-
- delete result;
- }
- while(guids && guids_itr != guids->end()); // not set case iterate single time, set case iterate for all guids
-}
-
-std::string PlayerDumpWriter::GetDump(uint32 guid)
-{
- std::string dump;
- for(int i = 0; i < DUMP_TABLE_COUNT; i++)
- DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type);
-
- // TODO: Add instance/group..
- // TODO: Add a dump level option to skip some non-important tables
-
- return dump;
-}
-
-DumpReturn PlayerDumpWriter::WriteDump(std::string file, uint32 guid)
-{
- FILE *fout = fopen(file.c_str(), "w");
- if (!fout)
- return DUMP_FILE_OPEN_ERROR;
-
- std::string dump = GetDump(guid);
-
- fprintf(fout,"%s\n",dump.c_str());
- fclose(fout);
- return DUMP_SUCCESS;
-}
-
-// Reading - High-level functions
-#define ROLLBACK(DR) {CharacterDatabase.RollbackTransaction(); fclose(fin); return (DR);}
-
-DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::string name, uint32 guid)
-{
- // check character count
- {
- QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", account);
- uint8 charcount = 0;
- if ( result )
- {
- Field *fields=result->Fetch();
- charcount = fields[0].GetUInt8();
- delete result;
-
- if (charcount >= 10)
- return DUMP_TOO_MANY_CHARS;
- }
- }
- FILE *fin = fopen(file.c_str(), "r");
- if(!fin)
- return DUMP_FILE_OPEN_ERROR;
-
- QueryResult * result = NULL;
- char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20];
-
- // make sure the same guid doesn't already exist and is safe to use
- bool incHighest = true;
- if(guid != 0 && guid < objmgr.m_hiCharGuid)
- {
- result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid);
- if (result)
- {
- guid = objmgr.m_hiCharGuid; // use first free if exists
- delete result;
- }
- else incHighest = false;
- }
- else guid = objmgr.m_hiCharGuid;
-
- // normalize the name if specified and check if it exists
- if(!normalizePlayerName(name))
- name = "";
-
- if(ObjectMgr::IsValidName(name,true))
- {
- CharacterDatabase.escape_string(name); // for safe, we use name only for sql quearies anyway
- result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE name = '%s'", name.c_str());
- if (result)
- {
- name = ""; // use the one from the dump
- delete result;
- }
- }
- else name = "";
-
- // name encoded or empty
-
- snprintf(newguid, 20, "%d", guid);
- snprintf(chraccount, 20, "%d", account);
- snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber());
- snprintf(lastpetid, 20, "%s", "");
-
- std::map<uint32,uint32> items;
- std::map<uint32,uint32> mails;
- char buf[32000] = "";
-
- typedef std::map<uint32, uint32> PetIds; // old->new petid relation
- typedef PetIds::value_type PetIdsPair;
- PetIds petids;
-
- CharacterDatabase.BeginTransaction();
- while(!feof(fin))
- {
- if(!fgets(buf, 32000, fin))
- {
- if(feof(fin)) break;
- ROLLBACK(DUMP_FILE_BROKEN);
- }
-
- std::string line; line.assign(buf);
-
- // skip empty strings
- if(line.find_first_not_of(" \t\n\r\7")==std::string::npos)
- continue;
-
- // determine table name and load type
- std::string tn = gettablename(line);
- if(tn.empty())
- {
- sLog.outError("LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str());
- ROLLBACK(DUMP_FILE_BROKEN);
- }
-
- DumpTableType type;
- uint8 i;
- for(i = 0; i < DUMP_TABLE_COUNT; i++)
- {
- if (tn == dumpTables[i].name)
- {
- type = dumpTables[i].type;
- break;
- }
- }
-
- if (i == DUMP_TABLE_COUNT)
- {
- sLog.outError("LoadPlayerDump: Unknown table: '%s'!", tn.c_str());
- ROLLBACK(DUMP_FILE_BROKEN);
- }
-
- // change the data to server values
- switch(type)
- {
- case DTT_CHAR_TABLE:
- if(!changenth(line, 1, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
- break;
-
- case DTT_CHARACTER: // character t.
- {
- if(!changenth(line, 1, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- // guid, data field:guid, items
- if(!changenth(line, 2, chraccount))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- std::string vals = getnth(line, 3);
- if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++)
- if(!changetokGuid(vals, field+1, items, objmgr.m_hiItemGuid, true))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- if(!changenth(line, 3, vals.c_str()))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- if (name == "")
- {
- // check if the original name already exists
- name = getnth(line, 4);
- CharacterDatabase.escape_string(name);
-
- result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE name = '%s'", name.c_str());
- if (result)
- {
- delete result;
- // rename on login: `at_login` field 30 in raw field list
- if(!changenth(line, 30, "1"))
- ROLLBACK(DUMP_FILE_BROKEN);
- }
- }
- else if(!changenth(line, 4, name.c_str()))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- break;
- }
- case DTT_INVENTORY: // character_inventory t.
- {
- if(!changenth(line, 1, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- // bag, item
- if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid, true))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changeGuid(line, 4, items, objmgr.m_hiItemGuid))
- ROLLBACK(DUMP_FILE_BROKEN);
- break;
- }
- case DTT_ITEM: // item_instance t.
- {
- // item, owner, data field:item, owner guid
- if(!changeGuid(line, 1, items, objmgr.m_hiItemGuid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changenth(line, 2, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- std::string vals = getnth(line,3);
- if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, objmgr.m_hiItemGuid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changenth(line, 3, vals.c_str()))
- ROLLBACK(DUMP_FILE_BROKEN);
- break;
- }
- case DTT_ITEM_GIFT: // character_gift
- {
- // guid,item_guid,
- if(!changenth(line, 1, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid))
- ROLLBACK(DUMP_FILE_BROKEN);
- break;
- }
- case DTT_PET: // character_pet t
- {
- //store a map of old pet id to new inserted pet id for use by type 5 tables
- snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
- if(strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid);
- if(strcmp(lastpetid,currpetid)!=0)
- {
- snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber());
- snprintf(lastpetid, 20, "%s", currpetid);
- }
-
- std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
-
- if(petids_iter == petids.end())
- {
- petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid)));
- }
-
- // item, entry, owner, ...
- if(!changenth(line, 1, newpetid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changenth(line, 3, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- break;
- }
- case DTT_PET_TABLE: // pet_aura, pet_spell, pet_spell_cooldown t
- {
- snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
-
- // lookup currpetid and match to new inserted pet id
- std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
- if(petids_iter == petids.end()) // couldn't find new inserted id
- ROLLBACK(DUMP_FILE_BROKEN);
-
- snprintf(newpetid, 20, "%d", petids_iter->second);
-
- if(!changenth(line, 1, newpetid))
- ROLLBACK(DUMP_FILE_BROKEN);
-
- break;
- }
- case DTT_MAIL: // mail
- {
- // id,messageType,stationery,sender,receiver
- if(!changeGuid(line, 1, mails, objmgr.m_mailid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changenth(line, 5, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
- break;
- }
- case DTT_MAIL_ITEM: // mail_items
- {
- // mail_id,item_guid,item_template,receiver
- if(!changeGuid(line, 1, mails, objmgr.m_mailid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid))
- ROLLBACK(DUMP_FILE_BROKEN);
- if(!changenth(line, 4, newguid))
- ROLLBACK(DUMP_FILE_BROKEN);
- break;
- }
- default:
- sLog.outError("Unknown dump table type: %u",type);
- break;
- }
-
- if(!CharacterDatabase.Execute(line.c_str()))
- ROLLBACK(DUMP_FILE_BROKEN);
- }
-
- CharacterDatabase.CommitTransaction();
-
- objmgr.m_hiItemGuid += items.size();
- objmgr.m_mailid += mails.size();
-
- if(incHighest)
- ++objmgr.m_hiCharGuid;
-
- fclose(fin);
-
- return DUMP_SUCCESS;
-}
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "PlayerDump.h"
+#include "Database/DatabaseEnv.h"
+#include "Database/SQLStorage.h"
+#include "UpdateFields.h"
+#include "ObjectMgr.h"
+
+// Character Dump tables
+#define DUMP_TABLE_COUNT 19
+
+struct DumpTable
+{
+ char const* name;
+ DumpTableType type;
+};
+
+static DumpTable dumpTables[DUMP_TABLE_COUNT] =
+{
+ { "characters", DTT_CHARACTER },
+ { "character_queststatus", DTT_CHAR_TABLE },
+ { "character_reputation", DTT_CHAR_TABLE },
+ { "character_spell", DTT_CHAR_TABLE },
+ { "character_spell_cooldown", DTT_CHAR_TABLE },
+ { "character_action", DTT_CHAR_TABLE },
+ { "character_aura", DTT_CHAR_TABLE },
+ { "character_homebind", DTT_CHAR_TABLE },
+ { "character_ticket", DTT_CHAR_TABLE },
+ { "character_inventory", DTT_INVENTORY },
+ { "mail", DTT_MAIL },
+ { "mail_items", DTT_MAIL_ITEM },
+ { "item_instance", DTT_ITEM },
+ { "character_gifts", DTT_ITEM_GIFT },
+ { "item_text", DTT_ITEM_TEXT },
+ { "character_pet", DTT_PET },
+ { "pet_aura", DTT_PET_TABLE },
+ { "pet_spell", DTT_PET_TABLE },
+ { "pet_spell_cooldown", DTT_PET_TABLE },
+};
+
+// Low level functions
+static bool findtoknth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e)
+{
+ int i; s = e = 0;
+ std::string::size_type size = str.size();
+ for(i = 1; s < size && i < n; s++) if(str[s] == ' ') ++i;
+ if (i < n)
+ return false;
+
+ e = str.find(' ', s);
+
+ return e != std::string::npos;
+}
+
+std::string gettoknth(std::string &str, int n)
+{
+ std::string::size_type s = 0, e = 0;
+ if(!findtoknth(str, n, s, e))
+ return "";
+
+ return str.substr(s, e-s);
+}
+
+bool findnth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e)
+{
+ s = str.find("VALUES ('")+9;
+ if (s == std::string::npos) return false;
+
+ do
+ {
+ e = str.find("'",s);
+ if (e == std::string::npos) return false;
+ } while(str[e-1] == '\\');
+
+ for(int i = 1; i < n; i++)
+ {
+ do
+ {
+ s = e+4;
+ e = str.find("'",s);
+ if (e == std::string::npos) return false;
+ } while (str[e-1] == '\\');
+ }
+ return true;
+}
+
+std::string gettablename(std::string &str)
+{
+ std::string::size_type s = 13;
+ std::string::size_type e = str.find(_TABLE_SIM_, s);
+ if (e == std::string::npos)
+ return "";
+
+ return str.substr(s, e-s);
+}
+
+bool changenth(std::string &str, int n, const char *with, bool insert = false, bool nonzero = false)
+{
+ std::string::size_type s, e;
+ if(!findnth(str,n,s,e))
+ return false;
+
+ if(nonzero && str.substr(s,e-s) == "0")
+ return true; // not an error
+ if(!insert)
+ str.replace(s,e-s, with);
+ else
+ str.insert(s, with);
+
+ return true;
+}
+
+std::string getnth(std::string &str, int n)
+{
+ std::string::size_type s, e;
+ if(!findnth(str,n,s,e))
+ return "";
+
+ return str.substr(s, e-s);
+}
+
+bool changetoknth(std::string &str, int n, const char *with, bool insert = false, bool nonzero = false)
+{
+ std::string::size_type s = 0, e = 0;
+ if(!findtoknth(str, n, s, e))
+ return false;
+ if(nonzero && str.substr(s,e-s) == "0")
+ return true; // not an error
+ if(!insert)
+ str.replace(s, e-s, with);
+ else
+ str.insert(s, with);
+
+ return true;
+}
+
+uint32 registerNewGuid(uint32 oldGuid, std::map<uint32, uint32> &guidMap, uint32 hiGuid)
+{
+ std::map<uint32, uint32>::iterator itr = guidMap.find(oldGuid);
+ if(itr != guidMap.end())
+ return itr->second;
+
+ uint32 newguid = hiGuid + guidMap.size();
+ guidMap[oldGuid] = newguid;
+ return newguid;
+}
+
+bool changeGuid(std::string &str, int n, std::map<uint32, uint32> &guidMap, uint32 hiGuid, bool nonzero = false)
+{
+ char chritem[20];
+ uint32 oldGuid = atoi(getnth(str, n).c_str());
+ if (nonzero && oldGuid == 0)
+ return true; // not an error
+
+ uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid);
+ snprintf(chritem, 20, "%d", newGuid);
+
+ return changenth(str, n, chritem, false, nonzero);
+}
+
+bool changetokGuid(std::string &str, int n, std::map<uint32, uint32> &guidMap, uint32 hiGuid, bool nonzero = false)
+{
+ char chritem[20];
+ uint32 oldGuid = atoi(gettoknth(str, n).c_str());
+ if (nonzero && oldGuid == 0)
+ return true; // not an error
+
+ uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid);
+ snprintf(chritem, 20, "%d", newGuid);
+
+ return changetoknth(str, n, chritem, false, nonzero);
+}
+
+std::string CreateDumpString(char const* tableName, QueryResult *result)
+{
+ if(!tableName || !result) return "";
+ std::ostringstream ss;
+ ss << "INSERT INTO "<< _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES (";
+ Field *fields = result->Fetch();
+ for(uint32 i = 0; i < result->GetFieldCount(); i++)
+ {
+ if (i == 0) ss << "'";
+ else ss << ", '";
+
+ std::string s = fields[i].GetCppString();
+ CharacterDatabase.escape_string(s);
+ ss << s;
+
+ ss << "'";
+ }
+ ss << ");";
+ return ss.str();
+}
+
+std::string PlayerDumpWriter::GenerateWhereStr(char const* field, uint32 guid)
+{
+ std::ostringstream wherestr;
+ wherestr << field << " = '" << guid << "'";
+ return wherestr.str();
+}
+
+std::string PlayerDumpWriter::GenerateWhereStr(char const* field, GUIDs const& guids, GUIDs::const_iterator& itr)
+{
+ std::ostringstream wherestr;
+ wherestr << field << " IN ('";
+ for(; itr != guids.end(); ++itr)
+ {
+ wherestr << *itr;
+
+ if(wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query
+ {
+ ++itr;
+ break;
+ }
+
+ GUIDs::const_iterator itr2 = itr;
+ if(++itr2 != guids.end())
+ wherestr << "','";
+ }
+ wherestr << "')";
+ return wherestr.str();
+}
+
+void StoreGUID(QueryResult *result,uint32 field,std::set<uint32>& guids)
+{
+ Field* fields = result->Fetch();
+ uint32 guid = fields[field].GetUInt32();
+ if(guid)
+ guids.insert(guid);
+}
+
+void StoreGUID(QueryResult *result,uint32 data,uint32 field, std::set<uint32>& guids)
+{
+ Field* fields = result->Fetch();
+ std::string dataStr = fields[data].GetCppString();
+ uint32 guid = atoi(gettoknth(dataStr, field).c_str());
+ if(guid)
+ guids.insert(guid);
+}
+
+// Writing - High-level functions
+void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type)
+{
+ GUIDs const* guids = NULL;
+ char const* fieldname = NULL;
+
+ switch ( type )
+ {
+ case DTT_ITEM: fieldname = "guid"; guids = &items; break;
+ case DTT_ITEM_GIFT: fieldname = "item_guid"; guids = &items; break;
+ case DTT_PET: fieldname = "owner"; break;
+ case DTT_PET_TABLE: fieldname = "guid"; guids = &pets; break;
+ case DTT_MAIL: fieldname = "receiver"; break;
+ case DTT_MAIL_ITEM: fieldname = "mail_id"; guids = &mails; break;
+ case DTT_ITEM_TEXT: fieldname = "id"; guids = &texts; break;
+ default: fieldname = "guid"; break;
+ }
+
+ // for guid set stop if set is empty
+ if(guids && guids->empty())
+ return; // nothing to do
+
+ // setup for guids case start position
+ GUIDs::const_iterator guids_itr;
+ if(guids)
+ guids_itr = guids->begin();
+
+ do
+ {
+ std::string wherestr;
+
+ if(guids) // set case, get next guids string
+ wherestr = GenerateWhereStr(fieldname,*guids,guids_itr);
+ else // not set case, get single guid string
+ wherestr = GenerateWhereStr(fieldname,guid);
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str());
+ if(!result)
+ return;
+
+ do
+ {
+ // collect guids
+ switch ( type )
+ {
+ case DTT_INVENTORY:
+ StoreGUID(result,3,items); break; // item guid collection
+ case DTT_ITEM:
+ StoreGUID(result,0,ITEM_FIELD_ITEM_TEXT_ID,texts); break;
+ // item text id collection
+ case DTT_PET:
+ StoreGUID(result,0,pets); break; // pet guid collection
+ case DTT_MAIL:
+ StoreGUID(result,0,mails); // mail id collection
+ StoreGUID(result,6,texts); break; // item text id collection
+ case DTT_MAIL_ITEM:
+ StoreGUID(result,1,items); break; // item guid collection
+ default: break;
+ }
+
+ dump += CreateDumpString(tableTo, result);
+ dump += "\n";
+ }
+ while (result->NextRow());
+
+ delete result;
+ }
+ while(guids && guids_itr != guids->end()); // not set case iterate single time, set case iterate for all guids
+}
+
+std::string PlayerDumpWriter::GetDump(uint32 guid)
+{
+ std::string dump;
+ for(int i = 0; i < DUMP_TABLE_COUNT; i++)
+ DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type);
+
+ // TODO: Add instance/group..
+ // TODO: Add a dump level option to skip some non-important tables
+
+ return dump;
+}
+
+DumpReturn PlayerDumpWriter::WriteDump(std::string file, uint32 guid)
+{
+ FILE *fout = fopen(file.c_str(), "w");
+ if (!fout)
+ return DUMP_FILE_OPEN_ERROR;
+
+ std::string dump = GetDump(guid);
+
+ fprintf(fout,"%s\n",dump.c_str());
+ fclose(fout);
+ return DUMP_SUCCESS;
+}
+
+// Reading - High-level functions
+#define ROLLBACK(DR) {CharacterDatabase.RollbackTransaction(); fclose(fin); return (DR);}
+
+DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::string name, uint32 guid)
+{
+ // check character count
+ {
+ QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", account);
+ uint8 charcount = 0;
+ if ( result )
+ {
+ Field *fields=result->Fetch();
+ charcount = fields[0].GetUInt8();
+ delete result;
+
+ if (charcount >= 10)
+ return DUMP_TOO_MANY_CHARS;
+ }
+ }
+
+ FILE *fin = fopen(file.c_str(), "r");
+ if(!fin)
+ return DUMP_FILE_OPEN_ERROR;
+
+ QueryResult * result = NULL;
+ char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20];
+
+ // make sure the same guid doesn't already exist and is safe to use
+ bool incHighest = true;
+ if(guid != 0 && guid < objmgr.m_hiCharGuid)
+ {
+ result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid);
+ if (result)
+ {
+ guid = objmgr.m_hiCharGuid; // use first free if exists
+ delete result;
+ }
+ else incHighest = false;
+ }
+ else
+ guid = objmgr.m_hiCharGuid;
+
+ // normalize the name if specified and check if it exists
+ if(!normalizePlayerName(name))
+ name = "";
+
+ if(ObjectMgr::IsValidName(name,true))
+ {
+ CharacterDatabase.escape_string(name); // for safe, we use name only for sql quearies anyway
+ result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE name = '%s'", name.c_str());
+ if (result)
+ {
+ name = ""; // use the one from the dump
+ delete result;
+ }
+ }
+ else name = "";
+
+ // name encoded or empty
+
+ snprintf(newguid, 20, "%d", guid);
+ snprintf(chraccount, 20, "%d", account);
+ snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber());
+ snprintf(lastpetid, 20, "%s", "");
+
+ std::map<uint32,uint32> items;
+ std::map<uint32,uint32> mails;
+ char buf[32000] = "";
+
+ typedef std::map<uint32, uint32> PetIds; // old->new petid relation
+ typedef PetIds::value_type PetIdsPair;
+ PetIds petids;
+
+ CharacterDatabase.BeginTransaction();
+ while(!feof(fin))
+ {
+ if(!fgets(buf, 32000, fin))
+ {
+ if(feof(fin)) break;
+ ROLLBACK(DUMP_FILE_BROKEN);
+ }
+
+ std::string line; line.assign(buf);
+
+ // skip empty strings
+ if(line.find_first_not_of(" \t\n\r\7")==std::string::npos)
+ continue;
+
+ // determine table name and load type
+ std::string tn = gettablename(line);
+ if(tn.empty())
+ {
+ sLog.outError("LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str());
+ ROLLBACK(DUMP_FILE_BROKEN);
+ }
+
+ DumpTableType type;
+ uint8 i;
+ for(i = 0; i < DUMP_TABLE_COUNT; i++)
+ {
+ if (tn == dumpTables[i].name)
+ {
+ type = dumpTables[i].type;
+ break;
+ }
+ }
+
+ if (i == DUMP_TABLE_COUNT)
+ {
+ sLog.outError("LoadPlayerDump: Unknown table: '%s'!", tn.c_str());
+ ROLLBACK(DUMP_FILE_BROKEN);
+ }
+
+ // change the data to server values
+ switch(type)
+ {
+ case DTT_CHAR_TABLE:
+ if(!changenth(line, 1, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ break;
+
+ case DTT_CHARACTER: // character t.
+ {
+ if(!changenth(line, 1, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ // guid, data field:guid, items
+ if(!changenth(line, 2, chraccount))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ std::string vals = getnth(line, 3);
+ if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++)
+ if(!changetokGuid(vals, field+1, items, objmgr.m_hiItemGuid, true))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changenth(line, 3, vals.c_str()))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if (name == "")
+ {
+ // check if the original name already exists
+ name = getnth(line, 4);
+ CharacterDatabase.escape_string(name);
+
+ result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE name = '%s'", name.c_str());
+ if (result)
+ {
+ delete result;
+ // rename on login: `at_login` field 30 in raw field list
+ if(!changenth(line, 30, "1"))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ }
+ }
+ else if(!changenth(line, 4, name.c_str()))
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ break;
+ }
+ case DTT_INVENTORY: // character_inventory t.
+ {
+ if(!changenth(line, 1, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ // bag, item
+ if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid, true))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changeGuid(line, 4, items, objmgr.m_hiItemGuid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ break;
+ }
+ case DTT_ITEM: // item_instance t.
+ {
+ // item, owner, data field:item, owner guid
+ if(!changeGuid(line, 1, items, objmgr.m_hiItemGuid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changenth(line, 2, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ std::string vals = getnth(line,3);
+ if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, objmgr.m_hiItemGuid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changenth(line, 3, vals.c_str()))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ break;
+ }
+ case DTT_ITEM_GIFT: // character_gift
+ {
+ // guid,item_guid,
+ if(!changenth(line, 1, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ break;
+ }
+ case DTT_PET: // character_pet t
+ {
+ //store a map of old pet id to new inserted pet id for use by type 5 tables
+ snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
+ if(strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid);
+ if(strcmp(lastpetid,currpetid)!=0)
+ {
+ snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber());
+ snprintf(lastpetid, 20, "%s", currpetid);
+ }
+
+ std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
+
+ if(petids_iter == petids.end())
+ {
+ petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid)));
+ }
+
+ // item, entry, owner, ...
+ if(!changenth(line, 1, newpetid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changenth(line, 3, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ break;
+ }
+ case DTT_PET_TABLE: // pet_aura, pet_spell, pet_spell_cooldown t
+ {
+ snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
+
+ // lookup currpetid and match to new inserted pet id
+ std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
+ if(petids_iter == petids.end()) // couldn't find new inserted id
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ snprintf(newpetid, 20, "%d", petids_iter->second);
+
+ if(!changenth(line, 1, newpetid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+
+ break;
+ }
+ case DTT_MAIL: // mail
+ {
+ // id,messageType,stationery,sender,receiver
+ if(!changeGuid(line, 1, mails, objmgr.m_mailid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changenth(line, 5, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ break;
+ }
+ case DTT_MAIL_ITEM: // mail_items
+ {
+ // mail_id,item_guid,item_template,receiver
+ if(!changeGuid(line, 1, mails, objmgr.m_mailid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ if(!changenth(line, 4, newguid))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ break;
+ }
+ default:
+ sLog.outError("Unknown dump table type: %u",type);
+ break;
+ }
+
+ if(!CharacterDatabase.Execute(line.c_str()))
+ ROLLBACK(DUMP_FILE_BROKEN);
+ }
+
+ CharacterDatabase.CommitTransaction();
+
+ objmgr.m_hiItemGuid += items.size();
+ objmgr.m_mailid += mails.size();
+
+ if(incHighest)
+ ++objmgr.m_hiCharGuid;
+
+ fclose(fin);
+
+ return DUMP_SUCCESS;
+}
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 3ed9c04a259..0e318eb5ddc 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -54,6 +54,12 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
return;
}
+ if(pItem->GetGUID() != item_guid)
+ {
+ pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
+ return;
+ }
+
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size());
ItemPrototype const *proto = pItem->GetProto();
@@ -237,7 +243,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
uint32 flags = fields[1].GetUInt32();
pItem->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0);
- pItem->SetUInt32Value(OBJECT_FIELD_ENTRY, entry);
+ pItem->SetEntry(entry);
pItem->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
pItem->SetState(ITEM_CHANGED, pUser);
delete result;
@@ -259,7 +265,6 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
CHECK_PACKET_SIZE(recv_data,8);
uint64 guid;
- uint32 spellId = OPEN_CHEST;
recv_data >> guid;
@@ -322,7 +327,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
}
Spell *spell = new Spell(_player, spellInfo, false);
- spell->m_cast_count = cast_count; //set count of casts
+ spell->m_cast_count = cast_count; // set count of casts
spell->prepare(&targets);
}
diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp
index d72ac1e266e..57c1734359b 100644
--- a/src/game/WaypointManager.cpp
+++ b/src/game/WaypointManager.cpp
@@ -1,278 +1,310 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "Database/DatabaseEnv.h"
-#include "GridDefines.h"
-#include "Policies/SingletonImp.h"
-#include "WaypointManager.h"
-#include "ProgressBar.h"
-#include "MapManager.h"
-
-INSTANTIATE_SINGLETON_1(WaypointManager);
-
-bool WaypointBehavior::isEmpty()
-{
- return emote == 0 && spell == 0 && model1 == 0 && model2 == 0 && text[0].empty() &&
- text[1].empty() && text[2].empty() && text[3].empty() && text[4].empty();
-}
-
-WaypointBehavior::WaypointBehavior(const WaypointBehavior &b)
-{
- emote = b.emote; spell = b.spell; model1 = b.model1; model2 = b.model2;
- text[0] = b.text[0]; text[1] = b.text[1]; text[2] = b.text[2];
- text[3] = b.text[3]; text[4] = b.text[4];
-}
-
-void WaypointManager::Load()
-{
- Cleanup();
-
- uint32 total_paths = 0;
- uint32 total_nodes = 0;
- uint32 total_behaviors = 0;
-
- QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");
- if(result)
- {
- total_paths = result->GetRowCount();
- barGoLink bar( total_paths );
- do
- {
- Field *fields = result->Fetch();
- uint32 id = fields[0].GetUInt32();
- uint32 count = fields[1].GetUInt32();
- m_pathMap[id].resize(count);
-
- total_nodes += count;
- bar.step();
- } while( result->NextRow() );
- delete result;
- }
-
- result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id, point FROM creature_movement");
- if(result)
- {
- barGoLink bar( result->GetRowCount() );
- do
- {
- Field *fields = result->Fetch();
- uint32 point = fields[15].GetUInt32();
- uint32 id = fields[14].GetUInt32();
-
- WaypointPath &path = m_pathMap[id];
- // the cleanup queries make sure the following is true
- assert(point >= 1 && point <= path.size());
- WaypointNode &node = path[point-1];
-
- node.x = fields[0].GetFloat();
- node.y = fields[1].GetFloat();
- node.z = fields[2].GetFloat();
- node.orientation = fields[3].GetFloat();
- node.delay = fields[6].GetUInt16();
-
- // prevent using invalid coordinates
- if(!Trinity::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
- {
- QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
- if(result1)
- sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
- id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
- else
- sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
- id, point, node.x, node.y);
-
- Trinity::NormalizeMapCoord(node.x);
- Trinity::NormalizeMapCoord(node.y);
- if(result1)
- {
- node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
- delete result1;
- }
- WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
- }
-
- WaypointBehavior be;
- be.model1 = fields[4].GetUInt32();
- be.model2 = fields[5].GetUInt32();
- be.emote = fields[7].GetUInt32();
- be.spell = fields[8].GetUInt32();
- be.text[0] = fields[9].GetCppString();
- be.text[1] = fields[10].GetCppString();
- be.text[2] = fields[11].GetCppString();
- be.text[3] = fields[12].GetCppString();
- be.text[4] = fields[13].GetCppString();
-
- // save memory by not storing empty behaviors
- if(!be.isEmpty())
- {
- node.behavior = new WaypointBehavior(be);
- ++total_behaviors;
- }
- else
- node.behavior = NULL;
- bar.step();
- } while( result->NextRow() );
- delete result;
- }
- sLog.outString( ">> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
-}
-
-void WaypointManager::Cleanup()
-{
- // check if points need to be renumbered and do it
- if(QueryResult *result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1"))
- {
- delete result;
- WorldDatabase.DirectExecute("CREATE TEMPORARY TABLE temp LIKE creature_movement");
- WorldDatabase.DirectExecute("INSERT INTO temp SELECT * FROM creature_movement");
- WorldDatabase.DirectExecute("ALTER TABLE creature_movement DROP PRIMARY KEY");
- WorldDatabase.DirectExecute("UPDATE creature_movement AS T SET point = (SELECT COUNT(*) FROM temp WHERE id = T.id AND point <= T.point)");
- WorldDatabase.DirectExecute("ALTER TABLE creature_movement ADD PRIMARY KEY (id, point)");
- WorldDatabase.DirectExecute("DROP TABLE temp");
- assert(!(result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1")));
- }
-}
-
-void WaypointManager::Unload()
-{
- for(WaypointPathMap::iterator itr = m_pathMap.begin(); itr != m_pathMap.end(); ++itr)
- _clearPath(itr->second);
- m_pathMap.clear();
-}
-
-void WaypointManager::_clearPath(WaypointPath &path)
-{
- for(WaypointPath::iterator itr = path.begin(); itr != path.end(); ++itr)
- if(itr->behavior)
- delete itr->behavior;
- path.clear();
-}
-
-/// - Insert after the last point
-void WaypointManager::AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
-{
- _addNode(id, GetLastPoint(id, 0) + 1, x, y, z, o, delay, wpGuid);
-}
-
-/// - Insert after a certain point
-void WaypointManager::AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
-{
- for(uint32 i = GetLastPoint(id, 0); i > point; i--)
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point+1 WHERE id='%u' AND point='%u'", id, i);
-
- _addNode(id, point + 1, x, y, z, o, delay, wpGuid);
-}
-
-/// - Insert without checking for collision
-void WaypointManager::_addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
-{
- if(point == 0) return; // counted from 1 in the DB
- WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z,orientation,wpguid,waittime) VALUES ('%u','%u','%f', '%f', '%f', '%f', '%d', '%d')", id, point, x, y, z, o, wpGuid, delay);
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- if(itr == m_pathMap.end())
- itr = m_pathMap.insert(WaypointPathMap::value_type(id, WaypointPath())).first;
- itr->second.insert(itr->second.begin() + (point - 1), WaypointNode(x, y, z, o, delay, NULL));
-}
-
-uint32 WaypointManager::GetLastPoint(uint32 id, uint32 default_notfound)
-{
- uint32 point = default_notfound;
- /*QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'", id);
- if( result )
- {
- point = (*result)[0].GetUInt32()+1;
- delete result;
- }*/
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- if(itr != m_pathMap.end() && itr->second.size() != 0)
- point = itr->second.size();
- return point;
-}
-
-void WaypointManager::DeleteNode(uint32 id, uint32 point)
-{
- if(point == 0) return; // counted from 1 in the DB
- WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u' AND point='%u'", id, point);
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point-1 WHERE id='%u' AND point>'%u'", id, point);
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- if(itr != m_pathMap.end() && point <= itr->second.size())
- itr->second.erase(itr->second.begin() + (point-1));
-}
-
-void WaypointManager::DeletePath(uint32 id)
-{
- WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u'", id);
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- if(itr != m_pathMap.end())
- _clearPath(itr->second);
- // the path is not removed from the map, just cleared
- // WMGs have pointers to the path, so deleting them would crash
- // this wastes some memory, but these functions are
- // only meant to be called by GM commands
-}
-
-void WaypointManager::SetNodePosition(uint32 id, uint32 point, float x, float y, float z)
-{
- if(point == 0) return; // counted from 1 in the DB
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'", x, y, z, id, point);
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- if(itr != m_pathMap.end() && point <= itr->second.size())
- {
- itr->second[point-1].x = x;
- itr->second[point-1].y = y;
- itr->second[point-1].z = z;
- }
-}
-
-void WaypointManager::SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text)
-{
- if(point == 0) return; // counted from 1 in the DB
- if(!text_field) return;
- std::string field = text_field;
- WorldDatabase.escape_string(field);
-
- if(!text)
- {
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s=NULL WHERE id='%u' AND point='%u'", field.c_str(), id, point);
- }
- else
- {
- std::string text2 = text;
- WorldDatabase.escape_string(text2);
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s='%s' WHERE id='%u' AND point='%u'", field.c_str(), text2.c_str(), id, point);
- }
-
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- if(itr != m_pathMap.end() && point <= itr->second.size())
- {
- WaypointNode &node = itr->second[point-1];
- if(!node.behavior) node.behavior = new WaypointBehavior();
-
- if(field == "text1") node.behavior->text[0] = text ? text : "";
- if(field == "text2") node.behavior->text[1] = text ? text : "";
- if(field == "text3") node.behavior->text[2] = text ? text : "";
- if(field == "text4") node.behavior->text[3] = text ? text : "";
- if(field == "text5") node.behavior->text[4] = text ? text : "";
- if(field == "emote") node.behavior->emote = text ? atoi(text) : 0;
- if(field == "spell") node.behavior->spell = text ? atoi(text) : 0;
- if(field == "model1") node.behavior->model1 = text ? atoi(text) : 0;
- if(field == "model2") node.behavior->model2 = text ? atoi(text) : 0;
- }
-}
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Database/DatabaseEnv.h"
+#include "GridDefines.h"
+#include "Policies/SingletonImp.h"
+#include "WaypointManager.h"
+#include "ProgressBar.h"
+#include "MapManager.h"
+#include "ObjectMgr.h"
+
+INSTANTIATE_SINGLETON_1(WaypointManager);
+
+bool WaypointBehavior::isEmpty()
+{
+ if (emote || spell || model1 || model2)
+ return false;
+
+ for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
+ if(textid[i])
+ return false;
+
+ return true;
+}
+
+WaypointBehavior::WaypointBehavior(const WaypointBehavior &b)
+{
+ emote = b.emote;
+ spell = b.spell;
+ model1 = b.model1;
+ model2 = b.model2;
+ for(int i=0; i < MAX_WAYPOINT_TEXT; ++i)
+ textid[i] = b.textid[i];
+}
+
+void WaypointManager::Load()
+{
+ Cleanup();
+
+ uint32 total_paths = 0;
+ uint32 total_nodes = 0;
+ uint32 total_behaviors = 0;
+
+ QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");
+ if(result)
+ {
+ total_paths = result->GetRowCount();
+ barGoLink bar( total_paths );
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 id = fields[0].GetUInt32();
+ uint32 count = fields[1].GetUInt32();
+ m_pathMap[id].resize(count);
+
+ total_nodes += count;
+ bar.step();
+ } while( result->NextRow() );
+ delete result;
+ }
+
+ result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement");
+ if(result)
+ {
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 point = fields[15].GetUInt32();
+ uint32 id = fields[14].GetUInt32();
+
+ WaypointPath &path = m_pathMap[id];
+ // the cleanup queries make sure the following is true
+ assert(point >= 1 && point <= path.size());
+ WaypointNode &node = path[point-1];
+
+ node.x = fields[0].GetFloat();
+ node.y = fields[1].GetFloat();
+ node.z = fields[2].GetFloat();
+ node.orientation = fields[3].GetFloat();
+ node.delay = fields[6].GetUInt16();
+
+ // prevent using invalid coordinates
+ if(!Trinity::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
+ {
+ QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
+ if(result1)
+ sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
+ id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
+ else
+ sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
+ id, point, node.x, node.y);
+
+ Trinity::NormalizeMapCoord(node.x);
+ Trinity::NormalizeMapCoord(node.y);
+ if(result1)
+ {
+ node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
+ delete result1;
+ }
+ WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
+ }
+
+ WaypointBehavior be;
+ be.model1 = fields[4].GetUInt32();
+ be.model2 = fields[5].GetUInt32();
+ be.emote = fields[7].GetUInt32();
+ be.spell = fields[8].GetUInt32();
+
+ // load and store without holes in array
+ int j = 0;
+ for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
+ {
+ be.textid[j] = fields[9+i].GetUInt32();
+ if(be.textid[j])
+ {
+ if (be.textid[j] < MIN_DB_SCRIPT_STRING_ID || be.textid[j] >= MAX_DB_SCRIPT_STRING_ID)
+ {
+ sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[j]);
+ continue;
+ }
+
+ if (!objmgr.GetTrinityStringLocale (be.textid[j]))
+ {
+ sLog.outErrorDb("ERROR: Waypoint path %d (point %d), have invalid text id (%i) in `textid%d, ignored.",
+ id, point, be.textid[j], i+1);
+ continue;
+ }
+
+ ++j; // to next internal field
+ }
+ }
+ // fill array tail
+ for(; j < MAX_WAYPOINT_TEXT; ++j)
+ be.textid[j] = 0;
+
+ // save memory by not storing empty behaviors
+ if(!be.isEmpty())
+ {
+ node.behavior = new WaypointBehavior(be);
+ ++total_behaviors;
+ }
+ else
+ node.behavior = NULL;
+ bar.step();
+ } while( result->NextRow() );
+ delete result;
+ }
+ sLog.outString( ">> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
+}
+
+void WaypointManager::Cleanup()
+{
+ // check if points need to be renumbered and do it
+ if(QueryResult *result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1"))
+ {
+ delete result;
+ WorldDatabase.DirectExecute("CREATE TEMPORARY TABLE temp LIKE creature_movement");
+ WorldDatabase.DirectExecute("INSERT INTO temp SELECT * FROM creature_movement");
+ WorldDatabase.DirectExecute("ALTER TABLE creature_movement DROP PRIMARY KEY");
+ WorldDatabase.DirectExecute("UPDATE creature_movement AS T SET point = (SELECT COUNT(*) FROM temp WHERE id = T.id AND point <= T.point)");
+ WorldDatabase.DirectExecute("ALTER TABLE creature_movement ADD PRIMARY KEY (id, point)");
+ WorldDatabase.DirectExecute("DROP TABLE temp");
+ assert(!(result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1")));
+ }
+}
+
+void WaypointManager::Unload()
+{
+ for(WaypointPathMap::iterator itr = m_pathMap.begin(); itr != m_pathMap.end(); ++itr)
+ _clearPath(itr->second);
+ m_pathMap.clear();
+}
+
+void WaypointManager::_clearPath(WaypointPath &path)
+{
+ for(WaypointPath::iterator itr = path.begin(); itr != path.end(); ++itr)
+ if(itr->behavior)
+ delete itr->behavior;
+ path.clear();
+}
+
+/// - Insert after the last point
+void WaypointManager::AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
+{
+ _addNode(id, GetLastPoint(id, 0) + 1, x, y, z, o, delay, wpGuid);
+}
+
+/// - Insert after a certain point
+void WaypointManager::AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
+{
+ for(uint32 i = GetLastPoint(id, 0); i > point; i--)
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point+1 WHERE id='%u' AND point='%u'", id, i);
+
+ _addNode(id, point + 1, x, y, z, o, delay, wpGuid);
+}
+
+/// - Insert without checking for collision
+void WaypointManager::_addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
+{
+ if(point == 0) return; // counted from 1 in the DB
+ WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z,orientation,wpguid,waittime) VALUES ('%u','%u','%f', '%f', '%f', '%f', '%d', '%d')", id, point, x, y, z, o, wpGuid, delay);
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ if(itr == m_pathMap.end())
+ itr = m_pathMap.insert(WaypointPathMap::value_type(id, WaypointPath())).first;
+ itr->second.insert(itr->second.begin() + (point - 1), WaypointNode(x, y, z, o, delay, NULL));
+}
+
+uint32 WaypointManager::GetLastPoint(uint32 id, uint32 default_notfound)
+{
+ uint32 point = default_notfound;
+ /*QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'", id);
+ if( result )
+ {
+ point = (*result)[0].GetUInt32()+1;
+ delete result;
+ }*/
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ if(itr != m_pathMap.end() && itr->second.size() != 0)
+ point = itr->second.size();
+ return point;
+}
+
+void WaypointManager::DeleteNode(uint32 id, uint32 point)
+{
+ if(point == 0) return; // counted from 1 in the DB
+ WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u' AND point='%u'", id, point);
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point-1 WHERE id='%u' AND point>'%u'", id, point);
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ if(itr != m_pathMap.end() && point <= itr->second.size())
+ itr->second.erase(itr->second.begin() + (point-1));
+}
+
+void WaypointManager::DeletePath(uint32 id)
+{
+ WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u'", id);
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ if(itr != m_pathMap.end())
+ _clearPath(itr->second);
+ // the path is not removed from the map, just cleared
+ // WMGs have pointers to the path, so deleting them would crash
+ // this wastes some memory, but these functions are
+ // only meant to be called by GM commands
+}
+
+void WaypointManager::SetNodePosition(uint32 id, uint32 point, float x, float y, float z)
+{
+ if(point == 0) return; // counted from 1 in the DB
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'", x, y, z, id, point);
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ if(itr != m_pathMap.end() && point <= itr->second.size())
+ {
+ itr->second[point-1].x = x;
+ itr->second[point-1].y = y;
+ itr->second[point-1].z = z;
+ }
+}
+
+void WaypointManager::SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text)
+{
+ if(point == 0) return; // counted from 1 in the DB
+ if(!text_field) return;
+ std::string field = text_field;
+ WorldDatabase.escape_string(field);
+
+ if(!text)
+ {
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s=NULL WHERE id='%u' AND point='%u'", field.c_str(), id, point);
+ }
+ else
+ {
+ std::string text2 = text;
+ WorldDatabase.escape_string(text2);
+ WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s='%s' WHERE id='%u' AND point='%u'", field.c_str(), text2.c_str(), id, point);
+ }
+
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ if(itr != m_pathMap.end() && point <= itr->second.size())
+ {
+ WaypointNode &node = itr->second[point-1];
+ if(!node.behavior) node.behavior = new WaypointBehavior();
+
+// if(field == "text1") node.behavior->text[0] = text ? text : "";
+// if(field == "text2") node.behavior->text[1] = text ? text : "";
+// if(field == "text3") node.behavior->text[2] = text ? text : "";
+// if(field == "text4") node.behavior->text[3] = text ? text : "";
+// if(field == "text5") node.behavior->text[4] = text ? text : "";
+ if(field == "emote") node.behavior->emote = text ? atoi(text) : 0;
+ if(field == "spell") node.behavior->spell = text ? atoi(text) : 0;
+ if(field == "model1") node.behavior->model1 = text ? atoi(text) : 0;
+ if(field == "model2") node.behavior->model2 = text ? atoi(text) : 0;
+ }
+}
diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h
index 2fdf5622c2e..c7e8e0fb530 100644
--- a/src/game/WaypointManager.h
+++ b/src/game/WaypointManager.h
@@ -1,91 +1,92 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TRINITY_WAYPOINTMANAGER_H
-#define TRINITY_WAYPOINTMANAGER_H
-
-#include <vector>
-#include <string>
-#include "Utilities/UnorderedMap.h"
-
-struct WaypointBehavior
-{
- uint32 emote;
- uint32 spell;
- std::string text[5];
- uint32 model1;
- uint32 model2;
-
- bool isEmpty();
- WaypointBehavior() {}
- WaypointBehavior(const WaypointBehavior &b);
-};
-
-struct WaypointNode
-{
- float x;
- float y;
- float z;
- float orientation;
- uint32 delay;
- WaypointBehavior * behavior;
- WaypointNode() {}
- WaypointNode(float _x, float _y, float _z, float _o, uint32 _delay, WaypointBehavior * _behavior)
- : x(_x), y(_y), z(_z), orientation(_o), delay(_delay), behavior(_behavior) {}
-};
-
-typedef std::vector<WaypointNode> WaypointPath;
-
-class WaypointManager
-{
- public:
- WaypointManager() {}
- ~WaypointManager() { Unload(); }
-
- void Load();
- void Unload();
-
- void Cleanup();
-
- WaypointPath *GetPath(uint32 id)
- {
- WaypointPathMap::iterator itr = m_pathMap.find(id);
- return itr != m_pathMap.end() ? &itr->second : NULL;
- }
-
- void AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
- void AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
- uint32 GetLastPoint(uint32 id, uint32 default_notfound);
- void DeleteNode(uint32 id, uint32 point);
- void DeletePath(uint32 id);
- void SetNodePosition(uint32 id, uint32 point, float x, float y, float z);
- void SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text);
-
- private:
- void _addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
- void _clearPath(WaypointPath &path);
-
- typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathMap;
- WaypointPathMap m_pathMap;
-};
-
-#define WaypointMgr Trinity::Singleton<WaypointManager>::Instance()
-
-#endif
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_WAYPOINTMANAGER_H
+#define TRINITY_WAYPOINTMANAGER_H
+
+#include <vector>
+#include <string>
+#include "Utilities/UnorderedMap.h"
+
+#define MAX_WAYPOINT_TEXT 5
+struct WaypointBehavior
+{
+ uint32 emote;
+ uint32 spell;
+ int32 textid[MAX_WAYPOINT_TEXT];
+ uint32 model1;
+ uint32 model2;
+
+ bool isEmpty();
+ WaypointBehavior() {}
+ WaypointBehavior(const WaypointBehavior &b);
+};
+
+struct WaypointNode
+{
+ float x;
+ float y;
+ float z;
+ float orientation;
+ uint32 delay;
+ WaypointBehavior * behavior;
+ WaypointNode() {}
+ WaypointNode(float _x, float _y, float _z, float _o, uint32 _delay, WaypointBehavior * _behavior)
+ : x(_x), y(_y), z(_z), orientation(_o), delay(_delay), behavior(_behavior) {}
+};
+
+typedef std::vector<WaypointNode> WaypointPath;
+
+class WaypointManager
+{
+ public:
+ WaypointManager() {}
+ ~WaypointManager() { Unload(); }
+
+ void Load();
+ void Unload();
+
+ void Cleanup();
+
+ WaypointPath *GetPath(uint32 id)
+ {
+ WaypointPathMap::iterator itr = m_pathMap.find(id);
+ return itr != m_pathMap.end() ? &itr->second : NULL;
+ }
+
+ void AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
+ void AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
+ uint32 GetLastPoint(uint32 id, uint32 default_notfound);
+ void DeleteNode(uint32 id, uint32 point);
+ void DeletePath(uint32 id);
+ void SetNodePosition(uint32 id, uint32 point, float x, float y, float z);
+ void SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text);
+
+ private:
+ void _addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
+ void _clearPath(WaypointPath &path);
+
+ typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathMap;
+ WaypointPathMap m_pathMap;
+};
+
+#define WaypointMgr Trinity::Singleton<WaypointManager>::Instance()
+
+#endif
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index ef3a8a04ef3..4de150a4af5 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -1,653 +1,652 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
-creature_movement Table
-
-alter table creature_movement add `text1` varchar(255) default NULL;
-alter table creature_movement add `text2` varchar(255) default NULL;
-alter table creature_movement add `text3` varchar(255) default NULL;
-alter table creature_movement add `text4` varchar(255) default NULL;
-alter table creature_movement add `text5` varchar(255) default NULL;
-alter table creature_movement add `emote` int(10) unsigned default '0';
-alter table creature_movement add `spell` int(5) unsigned default '0';
-alter table creature_movement add `wpguid` int(11) default '0';
-
-*/
-
-#include <ctime>
-
-#include "WaypointMovementGenerator.h"
-#include "ObjectMgr.h"
-#include "Creature.h"
-#include "DestinationHolderImp.h"
-#include "CreatureAI.h"
-#include "WaypointManager.h"
-
-#include <cassert>
-
-//-----------------------------------------------//
-void
-WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
-{
- sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow());
-
- i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow());
- if(!i_path)
- {
- sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s(%d) doesn't have waypoint path", c.GetName(), c.GetDBTableGUIDLow());
- return;
- }
-
- uint32 node_count = i_path->size();
- i_hasDone.resize(node_count);
- for(uint32 i = 0; i < node_count-1; i++)
- i_hasDone[i] = false;
-
- // to prevent a misbehaviour inside "update"
- // update is always called with the next wp - but the wpSys needs the current
- // so when the routine is called the first time, wpSys gets the last waypoint
- // and this prevents the system from performing text/emote, etc
- i_hasDone[node_count - 1] = true;
-}
-
-void
-WaypointMovementGenerator<Creature>::ClearWaypoints()
-{
- i_path = NULL;
-}
-
-void
-WaypointMovementGenerator<Creature>::Initialize()
-{
-}
-
-bool
-WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
-{
- if(!&creature)
- return true;
-
- // Waypoint movement can be switched on/off
- // This is quite handy for escort quests and other stuff
- if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
- return true;
-
- // prevent a crash at empty waypoint path.
- if(!i_path || i_path->empty())
- return true;
-
- // i_path was modified by chat commands for example
- if(i_path->size() != i_hasDone.size())
- i_hasDone.resize(i_path->size());
- if(i_currentNode >= i_path->size())
- i_currentNode = 0;
-
- CreatureTraveller traveller(creature);
-
- i_nextMoveTime.Update(diff);
- i_destinationHolder.UpdateTraveller(traveller, diff, false, true);
-
- // creature has been stoped in middle of the waypoint segment
- if (!i_destinationHolder.HasArrived() && creature.IsStopped())
- {
- if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it
- {
- SetStopedByPlayer(false);
- // Now we re-set destination to same node and start travel
- creature.addUnitState(UNIT_STAT_ROAMING);
- if (creature.canFly())
- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
- const WaypointNode &node = i_path->at(i_currentNode);
- i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
- }
- else // if( !i_nextMoveTime.Passed())
- { // unexpected end of timer && creature stopped && not at end of segment
- if (!IsStopedByPlayer())
- { // Put 30 seconds delay
- i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
- i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
- SetStopedByPlayer(true); // Mark we did it
- }
- }
- return true; // Abort here this update
- }
-
- if( creature.IsStopped())
- {
- uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;
-
- if (!i_hasDone[idx])
- {
- if (i_path->at(idx).orientation !=100)
- creature.SetOrientation(i_path->at(idx).orientation);
-
- if(WaypointBehavior *behavior = i_path->at(idx).behavior)
- {
- if(behavior->emote != 0)
- creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote);
- if(behavior->spell != 0)
- creature.CastSpell(&creature,behavior->spell, false);
- if(behavior->model1 != 0)
- creature.SetDisplayId(behavior->model1);
- if(!behavior->text[0].empty())
- {
- // Only one text is set
- if( !behavior->text[1].empty() )
- {
- // Select one from max 5 texts (0 and 1 already checked)
- int i = 2;
- for( ; i < 5; ++i )
- if( behavior->text[i].empty() )
- break;
-
- creature.Say(behavior->text[rand() % i].c_str(), 0, 0);
-
- }
- else
- creature.Say(behavior->text[0].c_str(), 0, 0);
- }
- } // wpBehaviour found
- i_hasDone[idx] = true;
- MovementInform(creature);
- } // HasDone == false
- } // i_creature.IsStopped()
-
- if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player
- {
- if( creature.IsStopped() ) // If stopped then begin a new move segment
- {
- creature.addUnitState(UNIT_STAT_ROAMING);
- if (creature.canFly())
- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
- const WaypointNode &node = i_path->at(i_currentNode);
- i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
- uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;
-
- if (i_path->at(idx).orientation !=100)
- creature.SetOrientation(i_path->at(idx).orientation);
-
- if(WaypointBehavior *behavior = i_path->at(idx).behavior )
- {
- i_hasDone[idx] = false;
- if(behavior->model2 != 0)
- creature.SetDisplayId(behavior->model2);
-
- creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- }
- }
- else // If not stopped then stop it and set the reset of TimeTracker to waittime
- {
- creature.StopMoving();
- SetStopedByPlayer(false);
- i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
- ++i_currentNode;
- if( i_currentNode >= i_path->size() )
- i_currentNode = 0;
- }
- }
- return true;
-}
-
-void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
-{
- if(unit.AI())
- unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
-}
-
-//----------------------------------------------------//
-void
-FlightPathMovementGenerator::LoadPath(Player &)
-{
- objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds);
-}
-
-uint32
-FlightPathMovementGenerator::GetPathAtMapEnd() const
-{
- if(i_currentNode >= i_mapIds.size())
- return i_mapIds.size();
-
- uint32 curMapId = i_mapIds[i_currentNode];
- for(uint32 i = i_currentNode; i < i_mapIds.size(); ++i)
- {
- if(i_mapIds[i] != curMapId)
- return i;
- }
-
- return i_mapIds.size();
-}
-
-void
-FlightPathMovementGenerator::Initialize(Player &player)
-{
- player.getHostilRefManager().setOnlineOfflineState(false);
- player.addUnitState(UNIT_STAT_IN_FLIGHT);
- player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
- LoadPath(player);
- Traveller<Player> traveller(player);
- // do not send movement, it was sent already
- i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false);
-
- player.SendMonsterMoveByPath(GetPath(),GetCurrentNode(),GetPathAtMapEnd(),MOVEMENTFLAG_WALK_MODE|MOVEMENTFLAG_ONTRANSPORT);
-}
-
-void FlightPathMovementGenerator::Finalize(Player & player)
-{
-
- float x, y, z;
- i_destinationHolder.GetLocationNow(player.GetMapId(), x, y, z);
- player.SetPosition(x, y, z, player.GetOrientation());
-
- player.clearUnitState(UNIT_STAT_IN_FLIGHT);
- player.Unmount();
- player.RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
-
- if(player.m_taxi.empty())
- {
- player.getHostilRefManager().setOnlineOfflineState(true);
- if(player.pvpInfo.inHostileArea)
- player.CastSpell(&player, 2479, true);
-
- player.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
- player.StopMoving();
- }
-}
-
-bool
-FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
-{
- if( MovementInProgress() )
- {
- Traveller<Player> traveller(player);
- if( i_destinationHolder.UpdateTraveller(traveller, diff, false) )
- {
- i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE);
- if( i_destinationHolder.HasArrived() )
- {
- uint32 curMap = i_mapIds[i_currentNode];
- ++i_currentNode;
- if( MovementInProgress() )
- {
- DEBUG_LOG("loading node %u for player %s", i_currentNode, player.GetName());
- if(i_mapIds[i_currentNode]==curMap)
- {
- // do not send movement, it was sent already
- i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false);
- }
- return true;
- }
- //else HasArrived()
- }
- else
- return true;
- }
- else
- return true;
- }
-
- // we have arrived at the end of the path
- return false;
-}
-
-void
-FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
-{
- if(i_mapIds.empty())
- return;
-
- uint32 map0 = i_mapIds[0];
- for(int i = 1; i < i_mapIds.size(); ++i)
- {
- if(i_mapIds[i]!=map0)
- {
- i_currentNode = i;
- return;
- }
- }
-}
-
-//
-// Unique1's ASTAR Pathfinding Code... For future use & reference...
-//
-
-#ifdef __PATHFINDING__
-
-int GetFCost(int to, int num, int parentNum, float *gcost); // Below...
-
-int ShortenASTARRoute(short int *pathlist, int number)
-{ // Wrote this to make the routes a little smarter (shorter)... No point looping back to the same places... Unique1
- short int temppathlist[MAX_PATHLIST_NODES];
- int count = 0;
- // int count2 = 0;
- int temp, temp2;
- int link;
- int upto = 0;
-
- for (temp = number; temp >= 0; temp--)
- {
- qboolean shortened = qfalse;
-
- for (temp2 = 0; temp2 < temp; temp2++)
- {
- for (link = 0; link < nodes[pathlist[temp]].enodenum; link++)
- {
- if (nodes[pathlist[temp]].links[link].flags & PATH_BLOCKED)
- continue;
-
- //if ((bot->client->ps.eFlags & EF_TANK) && nodes[bot->current_node].links[link].flags & PATH_NOTANKS) //if this path is blocked, skip it
- // continue;
-
- //if (nodes[nodes[pathlist[temp]].links[link].targetNode].origin[2] > nodes[pathlist[temp]].origin[2] + 32)
- // continue;
-
- if (nodes[pathlist[temp]].links[link].targetNode == pathlist[temp2])
- { // Found a shorter route...
- //if (OrgVisible(nodes[pathlist[temp2]].origin, nodes[pathlist[temp]].origin, -1))
- {
- temppathlist[count] = pathlist[temp2];
- temp = temp2;
- ++count;
- shortened = qtrue;
- }
- }
- }
- }
-
- if (!shortened)
- {
- temppathlist[count] = pathlist[temp];
- ++count;
- }
- }
-
- upto = count;
-
- for (temp = 0; temp < count; temp++)
- {
- pathlist[temp] = temppathlist[upto];
- --upto;
- }
-
- G_Printf("ShortenASTARRoute: Path size reduced from %i to %i nodes...n", number, count);
- return count;
-}
-
-/*
-===========================================================================
-CreatePathAStar
-This function uses the A* pathfinding algorithm to determine the
-shortest path between any two nodes.
-It's fairly complex, so I'm not really going to explain it much.
-Look up A* and binary heaps for more info.
-pathlist stores the ideal path between the nodes, in reverse order,
-and the return value is the number of nodes in that path
-===========================================================================
-*/
-int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist)
-{
- //all the data we have to hold...since we can't do dynamic allocation, has to be MAX_NODES
- //we can probably lower this later - eg, the open list should never have more than at most a few dozen items on it
- short int openlist[MAX_NODES+1]; //add 1 because it's a binary heap, and they don't use 0 - 1 is the first used index
- float gcost[MAX_NODES];
- int fcost[MAX_NODES];
- char list[MAX_NODES]; //0 is neither, 1 is open, 2 is closed - char because it's the smallest data type
- short int parent[MAX_NODES];
-
- short int numOpen = 0;
- short int atNode, temp, newnode=-1;
- qboolean found = qfalse;
- int count = -1;
- float gc;
- int i, u, v, m;
- vec3_t vec;
-
- //clear out all the arrays
- memset(openlist, 0, sizeof(short int)*(MAX_NODES+1));
- memset(fcost, 0, sizeof(int)*MAX_NODES);
- memset(list, 0, sizeof(char)*MAX_NODES);
- memset(parent, 0, sizeof(short int)*MAX_NODES);
- memset(gcost, -1, sizeof(float)*MAX_NODES);
-
- //make sure we have valid data before calculating everything
- if ((from == NODE_INVALID) || (to == NODE_INVALID) || (from >= MAX_NODES) || (to >= MAX_NODES) || (from == to))
- return -1;
-
- openlist[1] = from; //add the starting node to the open list
- ++numOpen;
- gcost[from] = 0; //its f and g costs are obviously 0
- fcost[from] = 0;
-
- while (1)
- {
- if (numOpen != 0) //if there are still items in the open list
- {
- //pop the top item off of the list
- atNode = openlist[1];
- list[atNode] = 2; //put the node on the closed list so we don't check it again
- --numOpen;
-
- openlist[1] = openlist[numOpen+1]; //move the last item in the list to the top position
- v = 1;
-
- //this while loop reorders the list so that the new lowest fcost is at the top again
- while (1)
- {
- u = v;
- if ((2*u+1) < numOpen) //if both children exist
- {
- if (fcost[openlist[u]] >= fcost[openlist[2*u]])
- v = 2*u;
- if (fcost[openlist[v]] >= fcost[openlist[2*u+1]])
- v = 2*u+1;
- }
- else
- {
- if ((2*u) < numOpen) //if only one child exists
- {
- if (fcost[openlist[u]] >= fcost[openlist[2*u]])
- v = 2*u;
- }
- }
-
- if (u != v) //if they're out of order, swap this item with its parent
- {
- temp = openlist[u];
- openlist[u] = openlist[v];
- openlist[v] = temp;
- }
- else
- break;
- }
-
- for (i = 0; i < nodes[atNode].enodenum; i++) //loop through all the links for this node
- {
- newnode = nodes[atNode].links[i].targetNode;
-
- //if this path is blocked, skip it
- if (nodes[atNode].links[i].flags & PATH_BLOCKED)
- continue;
- //if this path is blocked, skip it
- if (bot->client && (bot->client->ps.eFlags & EF_TANK) && nodes[atNode].links[i].flags & PATH_NOTANKS)
- continue;
- //skip any unreachable nodes
- if (bot->client && (nodes[newnode].type & NODE_ALLY_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_ALLIES))
- continue;
- if (bot->client && (nodes[newnode].type & NODE_AXIS_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_AXIS))
- continue;
-
- if (list[newnode] == 2) //if this node is on the closed list, skip it
- continue;
-
- if (list[newnode] != 1) //if this node is not already on the open list
- {
- openlist[++numOpen] = newnode; //add the new node to the open list
- list[newnode] = 1;
- parent[newnode] = atNode; //record the node's parent
-
- if (newnode == to) //if we've found the goal, don't keep computing paths!
- break; //this will break the 'for' and go all the way to 'if (list[to] == 1)'
-
- //store it's f cost value
- fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost);
-
- //this loop re-orders the heap so that the lowest fcost is at the top
- m = numOpen;
- while (m != 1) //while this item isn't at the top of the heap already
- {
- //if it has a lower fcost than its parent
- if (fcost[openlist[m]] <= fcost[openlist[m/2]])
- {
- temp = openlist[m/2];
- openlist[m/2] = openlist[m];
- openlist[m] = temp; //swap them
- m /= 2;
- }
- else
- break;
- }
- }
- else //if this node is already on the open list
- {
- gc = gcost[atNode];
- VectorSubtract(nodes[newnode].origin, nodes[atNode].origin, vec);
- gc += VectorLength(vec); //calculate what the gcost would be if we reached this node along the current path
-
- if (gc < gcost[newnode]) //if the new gcost is less (ie, this path is shorter than what we had before)
- {
- parent[newnode] = atNode; //set the new parent for this node
- gcost[newnode] = gc; //and the new g cost
-
- for (i = 1; i < numOpen; i++) //loop through all the items on the open list
- {
- if (openlist[i] == newnode) //find this node in the list
- {
- //calculate the new fcost and store it
- fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost);
-
- //reorder the list again, with the lowest fcost item on top
- m = i;
- while (m != 1)
- {
- //if the item has a lower fcost than it's parent
- if (fcost[openlist[m]] < fcost[openlist[m/2]])
- {
- temp = openlist[m/2];
- openlist[m/2] = openlist[m];
- openlist[m] = temp; //swap them
- m /= 2;
- }
- else
- break;
- }
- break; //exit the 'for' loop because we already changed this node
- } //if
- } //for
- } //if (gc < gcost[newnode])
- } //if (list[newnode] != 1) --> else
- } //for (loop through links)
- } //if (numOpen != 0)
- else
- {
- found = qfalse; //there is no path between these nodes
- break;
- }
-
- if (list[to] == 1) //if the destination node is on the open list, we're done
- {
- found = qtrue;
- break;
- }
- } //while (1)
-
- if (found == qtrue) //if we found a path
- {
- //G_Printf("%s - path found!n", bot->client->pers.netname);
- count = 0;
-
- temp = to; //start at the end point
- while (temp != from) //travel along the path (backwards) until we reach the starting point
- {
- pathlist[count++] = temp; //add the node to the pathlist and increment the count
- temp = parent[temp]; //move to the parent of this node to continue the path
- }
-
- pathlist[count++] = from; //add the beginning node to the end of the pathlist
-
- #ifdef __BOT_SHORTEN_ROUTING__
- count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1
- #endif //__BOT_SHORTEN_ROUTING__
- }
- else
- {
- //G_Printf("^1*** ^4BOT DEBUG^5: (CreatePathAStar) There is no route between node ^7%i^5 and node ^7%i^5.n", from, to);
- count = CreateDumbRoute(from, to, pathlist);
-
- if (count > 0)
- {
- #ifdef __BOT_SHORTEN_ROUTING__
- count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1
- #endif //__BOT_SHORTEN_ROUTING__
- return count;
- }
- }
-
- return count; //return the number of nodes in the path, -1 if not found
-}
-
-/*
-===========================================================================
-GetFCost
-Utility function used by A* pathfinding to calculate the
-cost to move between nodes towards a goal. Using the A*
-algorithm F = G + H, G here is the distance along the node
-paths the bot must travel, and H is the straight-line distance
-to the goal node.
-Returned as an int because more precision is unnecessary and it
-will slightly speed up heap access
-===========================================================================
-*/
-int GetFCost(int to, int num, int parentNum, float *gcost)
-{
- float gc = 0;
- float hc = 0;
- vec3_t v;
-
- if (gcost[num] == -1)
- {
- if (parentNum != -1)
- {
- gc = gcost[parentNum];
- VectorSubtract(nodes[num].origin, nodes[parentNum].origin, v);
- gc += VectorLength(v);
- }
- gcost[num] = gc;
- }
- else
- gc = gcost[num];
-
- VectorSubtract(nodes[to].origin, nodes[num].origin, v);
- hc = VectorLength(v);
-
- return (int)(gc + hc);
-}
-#endif //__PATHFINDING__
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+creature_movement Table
+
+alter table creature_movement add `textid1` int(11) NOT NULL default '0';
+alter table creature_movement add `textid2` int(11) NOT NULL default '0';
+alter table creature_movement add `textid3` int(11) NOT NULL default '0';
+alter table creature_movement add `textid4` int(11) NOT NULL default '0';
+alter table creature_movement add `textid5` int(11) NOT NULL default '0';
+alter table creature_movement add `emote` int(10) unsigned default '0';
+alter table creature_movement add `spell` int(5) unsigned default '0';
+alter table creature_movement add `wpguid` int(11) default '0';
+
+*/
+
+#include <ctime>
+
+#include "WaypointMovementGenerator.h"
+#include "ObjectMgr.h"
+#include "Creature.h"
+#include "DestinationHolderImp.h"
+#include "CreatureAI.h"
+#include "WaypointManager.h"
+
+#include <cassert>
+
+//-----------------------------------------------//
+void
+WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
+{
+ sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow());
+
+ i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow());
+ if(!i_path)
+ {
+ sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s(%d) doesn't have waypoint path", c.GetName(), c.GetDBTableGUIDLow());
+ return;
+ }
+
+ uint32 node_count = i_path->size();
+ i_hasDone.resize(node_count);
+ for(uint32 i = 0; i < node_count-1; i++)
+ i_hasDone[i] = false;
+
+ // to prevent a misbehaviour inside "update"
+ // update is always called with the next wp - but the wpSys needs the current
+ // so when the routine is called the first time, wpSys gets the last waypoint
+ // and this prevents the system from performing text/emote, etc
+ i_hasDone[node_count - 1] = true;
+}
+
+void
+WaypointMovementGenerator<Creature>::ClearWaypoints()
+{
+ i_path = NULL;
+}
+
+void
+WaypointMovementGenerator<Creature>::Initialize()
+{
+}
+
+bool
+WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
+{
+ if(!&creature)
+ return true;
+
+ // Waypoint movement can be switched on/off
+ // This is quite handy for escort quests and other stuff
+ if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ return true;
+
+ // prevent a crash at empty waypoint path.
+ if(!i_path || i_path->empty())
+ return true;
+
+ // i_path was modified by chat commands for example
+ if(i_path->size() != i_hasDone.size())
+ i_hasDone.resize(i_path->size());
+ if(i_currentNode >= i_path->size())
+ i_currentNode = 0;
+
+ CreatureTraveller traveller(creature);
+
+ i_nextMoveTime.Update(diff);
+ i_destinationHolder.UpdateTraveller(traveller, diff, false, true);
+
+ // creature has been stoped in middle of the waypoint segment
+ if (!i_destinationHolder.HasArrived() && creature.IsStopped())
+ {
+ if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it
+ {
+ SetStopedByPlayer(false);
+ // Now we re-set destination to same node and start travel
+ creature.addUnitState(UNIT_STAT_ROAMING);
+ if (creature.canFly())
+ creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+ const WaypointNode &node = i_path->at(i_currentNode);
+ i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+ }
+ else // if( !i_nextMoveTime.Passed())
+ { // unexpected end of timer && creature stopped && not at end of segment
+ if (!IsStopedByPlayer())
+ { // Put 30 seconds delay
+ i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
+ i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
+ SetStopedByPlayer(true); // Mark we did it
+ }
+ }
+ return true; // Abort here this update
+ }
+
+ if( creature.IsStopped())
+ {
+ uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;
+
+ if (!i_hasDone[idx])
+ {
+ if (i_path->at(idx).orientation !=100)
+ creature.SetOrientation(i_path->at(idx).orientation);
+
+ if(WaypointBehavior *behavior = i_path->at(idx).behavior)
+ {
+ if(behavior->emote != 0)
+ creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote);
+ if(behavior->spell != 0)
+ creature.CastSpell(&creature,behavior->spell, false);
+ if(behavior->model1 != 0)
+ creature.SetDisplayId(behavior->model1);
+ if(behavior->textid[0])
+ {
+ // Not only one text is set
+ if( behavior->textid[1] )
+ {
+ // Select one from max 5 texts (0 and 1 already checked)
+ int i = 2;
+ for( ; i < MAX_WAYPOINT_TEXT; ++i )
+ if( !behavior->textid[i] )
+ break;
+
+ creature.Say(behavior->textid[rand() % i], 0, 0);
+ }
+ else
+ creature.Say(behavior->textid[0], 0, 0);
+ }
+ } // wpBehaviour found
+ i_hasDone[idx] = true;
+ MovementInform(creature);
+ } // HasDone == false
+ } // i_creature.IsStopped()
+
+ if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player
+ {
+ if( creature.IsStopped() ) // If stopped then begin a new move segment
+ {
+ creature.addUnitState(UNIT_STAT_ROAMING);
+ if (creature.canFly())
+ creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+ const WaypointNode &node = i_path->at(i_currentNode);
+ i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+ uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;
+
+ if (i_path->at(idx).orientation !=100)
+ creature.SetOrientation(i_path->at(idx).orientation);
+
+ if(WaypointBehavior *behavior = i_path->at(idx).behavior )
+ {
+ i_hasDone[idx] = false;
+ if(behavior->model2 != 0)
+ creature.SetDisplayId(behavior->model2);
+
+ creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
+ }
+ }
+ else // If not stopped then stop it and set the reset of TimeTracker to waittime
+ {
+ creature.StopMoving();
+ SetStopedByPlayer(false);
+ i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
+ ++i_currentNode;
+ if( i_currentNode >= i_path->size() )
+ i_currentNode = 0;
+ }
+ }
+ return true;
+}
+
+void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
+{
+ if(unit.AI())
+ unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
+}
+
+//----------------------------------------------------//
+void
+FlightPathMovementGenerator::LoadPath(Player &)
+{
+ objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds);
+}
+
+uint32
+FlightPathMovementGenerator::GetPathAtMapEnd() const
+{
+ if(i_currentNode >= i_mapIds.size())
+ return i_mapIds.size();
+
+ uint32 curMapId = i_mapIds[i_currentNode];
+ for(uint32 i = i_currentNode; i < i_mapIds.size(); ++i)
+ {
+ if(i_mapIds[i] != curMapId)
+ return i;
+ }
+
+ return i_mapIds.size();
+}
+
+void
+FlightPathMovementGenerator::Initialize(Player &player)
+{
+ player.getHostilRefManager().setOnlineOfflineState(false);
+ player.addUnitState(UNIT_STAT_IN_FLIGHT);
+ player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
+ LoadPath(player);
+ Traveller<Player> traveller(player);
+ // do not send movement, it was sent already
+ i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false);
+
+ player.SendMonsterMoveByPath(GetPath(),GetCurrentNode(),GetPathAtMapEnd(),MOVEMENTFLAG_WALK_MODE|MOVEMENTFLAG_ONTRANSPORT);
+}
+
+void FlightPathMovementGenerator::Finalize(Player & player)
+{
+
+ float x, y, z;
+ i_destinationHolder.GetLocationNow(player.GetMapId(), x, y, z);
+ player.SetPosition(x, y, z, player.GetOrientation());
+
+ player.clearUnitState(UNIT_STAT_IN_FLIGHT);
+ player.Unmount();
+ player.RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
+
+ if(player.m_taxi.empty())
+ {
+ player.getHostilRefManager().setOnlineOfflineState(true);
+ if(player.pvpInfo.inHostileArea)
+ player.CastSpell(&player, 2479, true);
+
+ player.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+ player.StopMoving();
+ }
+}
+
+bool
+FlightPathMovementGenerator::Update(Player &player, const uint32 &diff)
+{
+ if( MovementInProgress() )
+ {
+ Traveller<Player> traveller(player);
+ if( i_destinationHolder.UpdateTraveller(traveller, diff, false) )
+ {
+ i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE);
+ if( i_destinationHolder.HasArrived() )
+ {
+ uint32 curMap = i_mapIds[i_currentNode];
+ ++i_currentNode;
+ if( MovementInProgress() )
+ {
+ DEBUG_LOG("loading node %u for player %s", i_currentNode, player.GetName());
+ if(i_mapIds[i_currentNode]==curMap)
+ {
+ // do not send movement, it was sent already
+ i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false);
+ }
+ return true;
+ }
+ //else HasArrived()
+ }
+ else
+ return true;
+ }
+ else
+ return true;
+ }
+
+ // we have arrived at the end of the path
+ return false;
+}
+
+void
+FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
+{
+ if(i_mapIds.empty())
+ return;
+
+ uint32 map0 = i_mapIds[0];
+ for(int i = 1; i < i_mapIds.size(); ++i)
+ {
+ if(i_mapIds[i]!=map0)
+ {
+ i_currentNode = i;
+ return;
+ }
+ }
+}
+
+//
+// Unique1's ASTAR Pathfinding Code... For future use & reference...
+//
+
+#ifdef __PATHFINDING__
+
+int GetFCost(int to, int num, int parentNum, float *gcost); // Below...
+
+int ShortenASTARRoute(short int *pathlist, int number)
+{ // Wrote this to make the routes a little smarter (shorter)... No point looping back to the same places... Unique1
+ short int temppathlist[MAX_PATHLIST_NODES];
+ int count = 0;
+ // int count2 = 0;
+ int temp, temp2;
+ int link;
+ int upto = 0;
+
+ for (temp = number; temp >= 0; temp--)
+ {
+ qboolean shortened = qfalse;
+
+ for (temp2 = 0; temp2 < temp; temp2++)
+ {
+ for (link = 0; link < nodes[pathlist[temp]].enodenum; link++)
+ {
+ if (nodes[pathlist[temp]].links[link].flags & PATH_BLOCKED)
+ continue;
+
+ //if ((bot->client->ps.eFlags & EF_TANK) && nodes[bot->current_node].links[link].flags & PATH_NOTANKS) //if this path is blocked, skip it
+ // continue;
+
+ //if (nodes[nodes[pathlist[temp]].links[link].targetNode].origin[2] > nodes[pathlist[temp]].origin[2] + 32)
+ // continue;
+
+ if (nodes[pathlist[temp]].links[link].targetNode == pathlist[temp2])
+ { // Found a shorter route...
+ //if (OrgVisible(nodes[pathlist[temp2]].origin, nodes[pathlist[temp]].origin, -1))
+ {
+ temppathlist[count] = pathlist[temp2];
+ temp = temp2;
+ ++count;
+ shortened = qtrue;
+ }
+ }
+ }
+ }
+
+ if (!shortened)
+ {
+ temppathlist[count] = pathlist[temp];
+ ++count;
+ }
+ }
+
+ upto = count;
+
+ for (temp = 0; temp < count; temp++)
+ {
+ pathlist[temp] = temppathlist[upto];
+ --upto;
+ }
+
+ G_Printf("ShortenASTARRoute: Path size reduced from %i to %i nodes...n", number, count);
+ return count;
+}
+
+/*
+===========================================================================
+CreatePathAStar
+This function uses the A* pathfinding algorithm to determine the
+shortest path between any two nodes.
+It's fairly complex, so I'm not really going to explain it much.
+Look up A* and binary heaps for more info.
+pathlist stores the ideal path between the nodes, in reverse order,
+and the return value is the number of nodes in that path
+===========================================================================
+*/
+int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist)
+{
+ //all the data we have to hold...since we can't do dynamic allocation, has to be MAX_NODES
+ //we can probably lower this later - eg, the open list should never have more than at most a few dozen items on it
+ short int openlist[MAX_NODES+1]; //add 1 because it's a binary heap, and they don't use 0 - 1 is the first used index
+ float gcost[MAX_NODES];
+ int fcost[MAX_NODES];
+ char list[MAX_NODES]; //0 is neither, 1 is open, 2 is closed - char because it's the smallest data type
+ short int parent[MAX_NODES];
+
+ short int numOpen = 0;
+ short int atNode, temp, newnode=-1;
+ qboolean found = qfalse;
+ int count = -1;
+ float gc;
+ int i, u, v, m;
+ vec3_t vec;
+
+ //clear out all the arrays
+ memset(openlist, 0, sizeof(short int)*(MAX_NODES+1));
+ memset(fcost, 0, sizeof(int)*MAX_NODES);
+ memset(list, 0, sizeof(char)*MAX_NODES);
+ memset(parent, 0, sizeof(short int)*MAX_NODES);
+ memset(gcost, -1, sizeof(float)*MAX_NODES);
+
+ //make sure we have valid data before calculating everything
+ if ((from == NODE_INVALID) || (to == NODE_INVALID) || (from >= MAX_NODES) || (to >= MAX_NODES) || (from == to))
+ return -1;
+
+ openlist[1] = from; //add the starting node to the open list
+ ++numOpen;
+ gcost[from] = 0; //its f and g costs are obviously 0
+ fcost[from] = 0;
+
+ while (1)
+ {
+ if (numOpen != 0) //if there are still items in the open list
+ {
+ //pop the top item off of the list
+ atNode = openlist[1];
+ list[atNode] = 2; //put the node on the closed list so we don't check it again
+ --numOpen;
+
+ openlist[1] = openlist[numOpen+1]; //move the last item in the list to the top position
+ v = 1;
+
+ //this while loop reorders the list so that the new lowest fcost is at the top again
+ while (1)
+ {
+ u = v;
+ if ((2*u+1) < numOpen) //if both children exist
+ {
+ if (fcost[openlist[u]] >= fcost[openlist[2*u]])
+ v = 2*u;
+ if (fcost[openlist[v]] >= fcost[openlist[2*u+1]])
+ v = 2*u+1;
+ }
+ else
+ {
+ if ((2*u) < numOpen) //if only one child exists
+ {
+ if (fcost[openlist[u]] >= fcost[openlist[2*u]])
+ v = 2*u;
+ }
+ }
+
+ if (u != v) //if they're out of order, swap this item with its parent
+ {
+ temp = openlist[u];
+ openlist[u] = openlist[v];
+ openlist[v] = temp;
+ }
+ else
+ break;
+ }
+
+ for (i = 0; i < nodes[atNode].enodenum; i++) //loop through all the links for this node
+ {
+ newnode = nodes[atNode].links[i].targetNode;
+
+ //if this path is blocked, skip it
+ if (nodes[atNode].links[i].flags & PATH_BLOCKED)
+ continue;
+ //if this path is blocked, skip it
+ if (bot->client && (bot->client->ps.eFlags & EF_TANK) && nodes[atNode].links[i].flags & PATH_NOTANKS)
+ continue;
+ //skip any unreachable nodes
+ if (bot->client && (nodes[newnode].type & NODE_ALLY_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_ALLIES))
+ continue;
+ if (bot->client && (nodes[newnode].type & NODE_AXIS_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_AXIS))
+ continue;
+
+ if (list[newnode] == 2) //if this node is on the closed list, skip it
+ continue;
+
+ if (list[newnode] != 1) //if this node is not already on the open list
+ {
+ openlist[++numOpen] = newnode; //add the new node to the open list
+ list[newnode] = 1;
+ parent[newnode] = atNode; //record the node's parent
+
+ if (newnode == to) //if we've found the goal, don't keep computing paths!
+ break; //this will break the 'for' and go all the way to 'if (list[to] == 1)'
+
+ //store it's f cost value
+ fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost);
+
+ //this loop re-orders the heap so that the lowest fcost is at the top
+ m = numOpen;
+ while (m != 1) //while this item isn't at the top of the heap already
+ {
+ //if it has a lower fcost than its parent
+ if (fcost[openlist[m]] <= fcost[openlist[m/2]])
+ {
+ temp = openlist[m/2];
+ openlist[m/2] = openlist[m];
+ openlist[m] = temp; //swap them
+ m /= 2;
+ }
+ else
+ break;
+ }
+ }
+ else //if this node is already on the open list
+ {
+ gc = gcost[atNode];
+ VectorSubtract(nodes[newnode].origin, nodes[atNode].origin, vec);
+ gc += VectorLength(vec); //calculate what the gcost would be if we reached this node along the current path
+
+ if (gc < gcost[newnode]) //if the new gcost is less (ie, this path is shorter than what we had before)
+ {
+ parent[newnode] = atNode; //set the new parent for this node
+ gcost[newnode] = gc; //and the new g cost
+
+ for (i = 1; i < numOpen; i++) //loop through all the items on the open list
+ {
+ if (openlist[i] == newnode) //find this node in the list
+ {
+ //calculate the new fcost and store it
+ fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost);
+
+ //reorder the list again, with the lowest fcost item on top
+ m = i;
+ while (m != 1)
+ {
+ //if the item has a lower fcost than it's parent
+ if (fcost[openlist[m]] < fcost[openlist[m/2]])
+ {
+ temp = openlist[m/2];
+ openlist[m/2] = openlist[m];
+ openlist[m] = temp; //swap them
+ m /= 2;
+ }
+ else
+ break;
+ }
+ break; //exit the 'for' loop because we already changed this node
+ } //if
+ } //for
+ } //if (gc < gcost[newnode])
+ } //if (list[newnode] != 1) --> else
+ } //for (loop through links)
+ } //if (numOpen != 0)
+ else
+ {
+ found = qfalse; //there is no path between these nodes
+ break;
+ }
+
+ if (list[to] == 1) //if the destination node is on the open list, we're done
+ {
+ found = qtrue;
+ break;
+ }
+ } //while (1)
+
+ if (found == qtrue) //if we found a path
+ {
+ //G_Printf("%s - path found!n", bot->client->pers.netname);
+ count = 0;
+
+ temp = to; //start at the end point
+ while (temp != from) //travel along the path (backwards) until we reach the starting point
+ {
+ pathlist[count++] = temp; //add the node to the pathlist and increment the count
+ temp = parent[temp]; //move to the parent of this node to continue the path
+ }
+
+ pathlist[count++] = from; //add the beginning node to the end of the pathlist
+
+ #ifdef __BOT_SHORTEN_ROUTING__
+ count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1
+ #endif //__BOT_SHORTEN_ROUTING__
+ }
+ else
+ {
+ //G_Printf("^1*** ^4BOT DEBUG^5: (CreatePathAStar) There is no route between node ^7%i^5 and node ^7%i^5.n", from, to);
+ count = CreateDumbRoute(from, to, pathlist);
+
+ if (count > 0)
+ {
+ #ifdef __BOT_SHORTEN_ROUTING__
+ count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1
+ #endif //__BOT_SHORTEN_ROUTING__
+ return count;
+ }
+ }
+
+ return count; //return the number of nodes in the path, -1 if not found
+}
+
+/*
+===========================================================================
+GetFCost
+Utility function used by A* pathfinding to calculate the
+cost to move between nodes towards a goal. Using the A*
+algorithm F = G + H, G here is the distance along the node
+paths the bot must travel, and H is the straight-line distance
+to the goal node.
+Returned as an int because more precision is unnecessary and it
+will slightly speed up heap access
+===========================================================================
+*/
+int GetFCost(int to, int num, int parentNum, float *gcost)
+{
+ float gc = 0;
+ float hc = 0;
+ vec3_t v;
+
+ if (gcost[num] == -1)
+ {
+ if (parentNum != -1)
+ {
+ gc = gcost[parentNum];
+ VectorSubtract(nodes[num].origin, nodes[parentNum].origin, v);
+ gc += VectorLength(v);
+ }
+ gcost[num] = gc;
+ }
+ else
+ gc = gcost[num];
+
+ VectorSubtract(nodes[to].origin, nodes[num].origin, v);
+ hc = VectorLength(v);
+
+ return (int)(gc + hc);
+}
+#endif //__PATHFINDING__
diff --git a/src/game/World.cpp b/src/game/World.cpp
index d6017ac0669..64c2bd49099 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \file
@@ -66,6 +66,7 @@
INSTANTIATE_SINGLETON_1( World );
volatile bool World::m_stopEvent = false;
+uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
volatile uint32 World::m_worldLoopCounter = 0;
float World::m_MaxVisibleDistanceForCreature = DEFAULT_VISIBILITY_DISTANCE;
@@ -542,7 +543,6 @@ void World::LoadConfigSettings(bool reload)
else
m_configs[CONFIG_SOCKET_SELECTTIME] = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME);
-
m_configs[CONFIG_GROUP_XP_DISTANCE] = sConfig.GetIntDefault("MaxGroupXPDistance", 74);
/// \todo Add MonsterSight and GuarderSight (with meaning) in Trinityd.conf or put them as define
m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 50);
@@ -605,7 +605,6 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_SKIP_CINEMATICS] = 0;
}
-
if(reload)
{
uint32 val = sConfig.GetIntDefault("MaxPlayerLevel", 60);
@@ -769,8 +768,8 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_THREAT_RADIUS] = sConfig.GetIntDefault("ThreatRadius", 100);
- // always use declined names in the Russian client
- m_configs[CONFIG_DECLINED_NAMES_USED] =
+ // always use declined names in the russian client
+ m_configs[CONFIG_DECLINED_NAMES_USED] =
(m_configs[CONFIG_REALM_ZONE] == REALM_ZONE_RUSSIAN) ? true : sConfig.GetBoolDefault("DeclinedNames", false);
m_configs[CONFIG_LISTEN_RANGE_SAY] = sConfig.GetIntDefault("ListenRange.Say", 25);
@@ -965,6 +964,9 @@ void World::SetInitialWorldSettings()
LoadDBCStores(m_dataPath);
DetectDBCLang();
+ sLog.outString( "Loading Script Names...");
+ objmgr.LoadScriptNames();
+
sLog.outString( "Loading InstanceTemplate" );
objmgr.LoadInstanceTemplate();
@@ -1080,11 +1082,10 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Tavern Area Triggers..." );
objmgr.LoadTavernAreaTriggers();
-
+
sLog.outString( "Loading AreaTrigger script names..." );
objmgr.LoadAreaTriggerScripts();
-
sLog.outString( "Loading Graveyard-zone links...");
objmgr.LoadGraveyardZones();
@@ -1164,7 +1165,7 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Npc Text Id..." );
objmgr.LoadNpcTextId(); // must be after load Creature and NpcText
-
+
sLog.outString( "Loading Npc Options..." );
objmgr.LoadNpcOptions();
@@ -1192,6 +1193,9 @@ void World::SetInitialWorldSettings()
objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data)
+ sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
+ objmgr.LoadDbScriptStrings();
+
sLog.outString( "Initializing Scripts..." );
if(!LoadScriptingModule())
exit(1);
@@ -1262,6 +1266,7 @@ void World::SetInitialWorldSettings()
sLog.outString( "WORLD: World initialized" );
}
+
void World::DetectDBCLang()
{
uint32 m_lang_confid = sConfig.GetIntDefault("DBC.Locale", 255);
@@ -1462,7 +1467,9 @@ void World::Update(time_t diff)
m_timers[WUPDATE_EVENTS].Reset();
}
- MapManager::Instance().DoDelayedMovesAndRemoves(); ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove"
+ /// </ul>
+ ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove"
+ MapManager::Instance().DoDelayedMovesAndRemoves();
// update the instance reset times
sInstanceSaveManager.Update();
@@ -1582,6 +1589,8 @@ void World::ScriptsProcess()
}
}
+ //if(source && !source->IsInWorld()) source = NULL;
+
Object* target = NULL;
if(step.targetGUID)
@@ -1609,6 +1618,8 @@ void World::ScriptsProcess()
}
}
+ //if(target && !target->IsInWorld()) target = NULL;
+
switch (step.script->command)
{
case SCRIPT_COMMAND_TALK:
@@ -1636,7 +1647,7 @@ void World::ScriptsProcess()
switch(step.script->datalong)
{
case 0: // Say
- ((Creature *)source)->Say(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target);
+ ((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 1: // Whisper
if(!unit_target)
@@ -1644,13 +1655,13 @@ void World::ScriptsProcess()
sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong);
break;
}
- ((Creature *)source)->Whisper(step.script->datatext.c_str(),unit_target);
+ ((Creature *)source)->Whisper(step.script->dataint,unit_target);
break;
case 2: // Yell
- ((Creature *)source)->Yell(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target);
+ ((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 3: // Emote text
- ((Creature *)source)->TextEmote(step.script->datatext.c_str(), unit_target);
+ ((Creature *)source)->TextEmote(step.script->dataint, unit_target);
break;
default:
break; // must be already checked at load
@@ -1701,7 +1712,7 @@ void World::ScriptsProcess()
break;
}
((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, ((Unit *)source)->GetUnitMovementFlags(), step.script->datalong2 );
- MapManager::Instance().GetMap(((Unit *)source)->GetMapId(), ((Unit *)source))->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0);
+ ((Unit *)source)->GetMap()->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:
if(!source)
@@ -1851,7 +1862,7 @@ void World::ScriptsProcess()
go->SetLootState(GO_READY);
go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds
- MapManager::Instance().GetMap(go->GetMapId(), go)->Add(go);
+ go->GetMap()->Add(go);
break;
}
case SCRIPT_COMMAND_OPEN_DOOR:
@@ -2373,13 +2384,13 @@ void World::_UpdateGameTime()
m_gameTime = thisTime;
///- if there is a shutdown timer
- if(m_ShutdownTimer > 0 && elapsed > 0)
+ if(!m_stopEvent && m_ShutdownTimer > 0 && elapsed > 0)
{
///- ... and it is overdue, stop the world (set m_stopEvent)
if( m_ShutdownTimer <= elapsed )
{
if(!(m_ShutdownMask & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount()==0)
- m_stopEvent = true;
+ m_stopEvent = true; // exist code already set
else
m_ShutdownTimer = 1; // minimum timer value to wait idle state
}
@@ -2394,15 +2405,20 @@ void World::_UpdateGameTime()
}
/// Shutdown the server
-void World::ShutdownServ(uint32 time, uint32 options)
+void World::ShutdownServ(uint32 time, uint32 options, uint8 exitcode)
{
+ // ignore if server shutdown at next tick
+ if(m_stopEvent)
+ return;
+
m_ShutdownMask = options;
+ m_ExitCode = exitcode;
///- If the shutdown time is 0, set m_stopEvent (except if shutdown is 'idle' with remaining sessions)
if(time==0)
{
if(!(options & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount()==0)
- m_stopEvent = true;
+ m_stopEvent = true; // exist code already set
else
m_ShutdownTimer = 1; //So that the session count is re-evaluated at next world tick
}
@@ -2447,16 +2463,18 @@ void World::ShutdownMsg(bool show, Player* player)
/// Cancel a planned server shutdown
void World::ShutdownCancel()
{
- if(!m_ShutdownTimer)
+ // nothing cancel or too later
+ if(!m_ShutdownTimer || m_stopEvent)
return;
uint32 msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED;
m_ShutdownMask = 0;
m_ShutdownTimer = 0;
+ m_ExitCode = SHUTDOWN_EXIT_CODE; // to default value
SendServerMessage(msgid);
- DEBUG_LOG("Server %s canceled.",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown"));
+ DEBUG_LOG("Server %s cancelled.",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown"));
}
/// Send a server message to the user(s)
@@ -2501,6 +2519,7 @@ void World::UpdateSessions( time_t diff )
///- and remove not active sessions from the list
if(!itr->second->Update(diff)) // As interval = 0
{
+ RemoveQueuedPlayer (itr->second);
delete itr->second;
m_sessions.erase(itr);
}
diff --git a/src/game/World.h b/src/game/World.h
index c1ceb6891a5..50065b360dd 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/// \addtogroup world The World
@@ -51,6 +51,13 @@ enum ShutdownMask
SHUTDOWN_MASK_IDLE = 2,
};
+enum ShutdownExitCode
+{
+ SHUTDOWN_EXIT_CODE = 0,
+ ERROR_EXIT_CODE = 1,
+ RESTART_EXIT_CODE = 2,
+};
+
/// Timers for different object refresh rates
enum WorldTimers
{
@@ -61,8 +68,7 @@ enum WorldTimers
WUPDATE_UPTIME = 4,
WUPDATE_CORPSES = 5,
WUPDATE_EVENTS = 6,
- WUPDATE_COUNT = 7,
-
+ WUPDATE_COUNT = 7
};
/// Configuration elements
@@ -105,6 +111,8 @@ enum WorldConfigs
CONFIG_INSTANCE_IGNORE_LEVEL,
CONFIG_INSTANCE_IGNORE_RAID,
CONFIG_BATTLEGROUND_CAST_DESERTER,
+ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
+ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_INSTANCE_RESET_TIME_HOUR,
CONFIG_INSTANCE_UNLOAD_DELAY,
CONFIG_CAST_UNSTUCK,
@@ -143,6 +151,7 @@ enum WorldConfigs
CONFIG_WORLD_BOSS_LEVEL_DIFF,
CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF,
CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF,
+ CONFIG_DETECT_POS_COLLISION,
CONFIG_RESTRICTED_LFG_CHANNEL,
CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL,
CONFIG_TALENTS_INSPECTING,
@@ -316,27 +325,26 @@ enum RealmZone
/// Storage class for commands issued for delayed execution
struct CliCommandHolder
{
- typedef void Print(const char*);
+ typedef void Print(const char*);
- char *m_command;
- Print* m_print;
+ char *m_command;
+ Print* m_print;
- CliCommandHolder(const char *command, Print* zprint)
- : m_print(zprint)
- {
- size_t len = strlen(command)+1;
- m_command = new char[len];
- memcpy(m_command, command, len);
- }
+ CliCommandHolder(const char *command, Print* zprint)
+ : m_print(zprint)
+ {
+ size_t len = strlen(command)+1;
+ m_command = new char[len];
+ memcpy(m_command, command, len);
+ }
- ~CliCommandHolder() { delete[] m_command; }
+ ~CliCommandHolder() { delete[] m_command; }
};
/// The World
class World
{
public:
- static volatile bool m_stopEvent;
static volatile uint32 m_worldLoopCounter;
World();
@@ -344,7 +352,6 @@ class World
WorldSession* FindSession(uint32 id) const;
void AddSession(WorldSession *s);
-
bool RemoveSession(uint32 id);
/// Get the number of current active sessions
void UpdateMaxSessionCounters();
@@ -407,18 +414,20 @@ class World
void SetInitialWorldSettings();
void LoadConfigSettings(bool reload = false);
- void SendWorldText(int32 string_id, ...);
+ void SendWorldText(int32 string_id, ...);
void SendGlobalMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0);
void SendServerMessage(uint32 type, const char *text = "", Player* player = NULL);
/// Are we in the middle of a shutdown?
- uint32 GetShutdownMask() const { return m_ShutdownMask; }
bool IsShutdowning() const { return m_ShutdownTimer > 0; }
- void ShutdownServ(uint32 time, uint32 options = 0);
+ void ShutdownServ(uint32 time, uint32 options, uint8 exitcode);
void ShutdownCancel();
void ShutdownMsg(bool show = false, Player* player = NULL);
+ static uint8 GetExitCode() { return m_ExitCode; }
+ static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; }
+ static bool IsStopped() { return m_stopEvent; }
void Update(time_t diff);
@@ -453,7 +462,7 @@ class World
void KickAllLess(AccountTypes sec);
void KickAllQueued();
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
- bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
+ bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
@@ -481,13 +490,13 @@ class World
LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const { if(m_availableDbcLocaleMask & (1 << locale)) return locale; else return m_defaultDbcLocale; }
- //used World DB version
- void LoadDBVersion();
- char const* GetDBVersion() { return m_DBVersion.c_str(); }
+ //used World DB version
+ void LoadDBVersion();
+ char const* GetDBVersion() { return m_DBVersion.c_str(); }
- //used Script version
- void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; }
- char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); }
+ //used Script version
+ void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; }
+ char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); }
protected:
void _UpdateGameTime();
@@ -498,6 +507,11 @@ class World
void InitDailyQuestResetTime();
void ResetDailyQuests();
private:
+ static volatile bool m_stopEvent;
+ static uint8 m_ExitCode;
+ uint32 m_ShutdownTimer;
+ uint32 m_ShutdownMask;
+
time_t m_startTime;
time_t m_gameTime;
IntervalTimer m_timers[WUPDATE_COUNT];
@@ -525,9 +539,6 @@ class World
std::string m_dataPath;
std::set<uint32> m_forbiddenMapIds;
- uint32 m_ShutdownTimer;
- uint32 m_ShutdownMask;
-
// for max speed access
static float m_MaxVisibleDistanceForCreature;
static float m_MaxVisibleDistanceForPlayer;
@@ -545,14 +556,14 @@ class World
//Player Queue
Queue m_QueuedPlayer;
-
+
//sessions that are added async
void AddSession_(WorldSession* s);
ZThread::LockedQueue<WorldSession*, ZThread::FastMutex> addSessQueue;
- //used versions
- std::string m_DBVersion;
- std::string m_ScriptsVersion;
+ //used versions
+ std::string m_DBVersion;
+ std::string m_ScriptsVersion;
};
extern uint32 realmID;
diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h
new file mode 100644
index 00000000000..9050aae8daa
--- /dev/null
+++ b/src/shared/Database/DBCEnums.h
@@ -0,0 +1,104 @@
+/*
+* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DBCENUMS_H
+#define DBCENUMS_H
+
+enum AreaTeams
+{
+ AREATEAM_NONE = 0,
+ AREATEAM_ALLY = 2,
+ AREATEAM_HORDE = 4
+};
+
+enum AreaFlags
+{
+ AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
+ AREA_FLAG_UNK1 = 0x00000002, // unknown, (only Naxxramas and Razorfen Downs)
+ AREA_FLAG_UNK2 = 0x00000004, // Only used on development map
+ AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // slave capital city flag?
+ AREA_FLAG_UNK3 = 0x00000010, // unknown
+ AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag?
+ AREA_FLAG_UNK4 = 0x00000040, // many zones have this flag
+ AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas
+ AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag
+ AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
+ AREA_FLAG_OUTLAND = 0x00000400, // outland zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
+ AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
+ AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway
+ AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 2.4.2)
+ AREA_FLAG_OUTLAND2 = 0x00004000, // outland zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
+ AREA_FLAG_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
+ AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only
+ AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 2.4.2)
+ AREA_FLAG_UNK5 = 0x00040000, // just used for Amani Pass, Hatchet Hills
+ AREA_FLAG_LOWLEVEL = 0x00100000 // used for some starting areas with area_level <=15
+};
+
+enum FactionTemplateFlags
+{
+ FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats
+};
+
+enum FactionMasks
+{
+ FACTION_MASK_PLAYER = 1, // any player
+ FACTION_MASK_ALLIANCE = 2, // player or creature from alliance team
+ FACTION_MASK_HORDE = 4, // player or creature from horde team
+ FACTION_MASK_MONSTER = 8 // aggressive creature from monster team
+ // if none flags set then non-aggressive creature
+};
+
+enum MapTypes
+{
+ MAP_COMMON = 0,
+ MAP_INSTANCE = 1,
+ MAP_RAID = 2,
+ MAP_BATTLEGROUND = 3,
+ MAP_ARENA = 4
+};
+
+enum AbilytyLearnType
+{
+ ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1,
+ ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2
+};
+
+enum ItemEnchantmentType
+{
+ ITEM_ENCHANTMENT_TYPE_NONE = 0,
+ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1,
+ ITEM_ENCHANTMENT_TYPE_DAMAGE = 2,
+ ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3,
+ ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4,
+ ITEM_ENCHANTMENT_TYPE_STAT = 5,
+ ITEM_ENCHANTMENT_TYPE_TOTEM = 6
+};
+
+enum TotemCategoryType
+{
+ TOTEM_CATEGORY_TYPE_KNIFE = 1,
+ TOTEM_CATEGORY_TYPE_TOTEM = 2,
+ TOTEM_CATEGORY_TYPE_ROD = 3,
+ TOTEM_CATEGORY_TYPE_PICK = 21,
+ TOTEM_CATEGORY_TYPE_STONE = 22,
+ TOTEM_CATEGORY_TYPE_HAMMER = 23,
+ TOTEM_CATEGORY_TYPE_SPANNER = 24
+};
+
+#endif
diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp
index 020cd53e61d..71e3483a1ab 100644
--- a/src/shared/Database/DBCStores.cpp
+++ b/src/shared/Database/DBCStores.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "DBCStores.h"
@@ -121,21 +121,9 @@ DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
// DBC used only for initialization sTaxiPathSetBySource at startup.
TaxiPathNodesByPath sTaxiPathNodesByPath;
-struct TaxiPathNodeEntry
-{
- uint32 path;
- uint32 index;
- uint32 mapid;
- float x;
- float y;
- float z;
- uint32 actionFlag;
- uint32 delay;
-};
-static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
+static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
-
DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
@@ -235,7 +223,7 @@ void LoadDBCStores(std::string dataPath)
flist.push_back(i);
}
}
-
+
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc");
@@ -283,21 +271,21 @@ void LoadDBCStores(std::string dataPath)
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
{
SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
-
+
if(!skillLine)
continue;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
if(spellInfo && (spellInfo->Attributes & 0x1D0) == 0x1D0)
- {
+ {
for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
{
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
if(!cFamily)
continue;
- if(skillLine->skillId != cFamily->skillLine && skillLine->skillId != cFamily->skillLine2)
+ if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1])
continue;
sPetFamilySpellsStore[i].insert(spellInfo->Id);
@@ -309,7 +297,6 @@ void LoadDBCStores(std::string dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc");
-
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc");
@@ -455,11 +442,11 @@ void LoadDBCStores(std::string dataPath)
// check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3)
// check at up-to-date DBC files (71 is last char title added in 2.4.3)
// check at up-to-date DBC files (1768 is last area added in 2.4.3)
- if( !sSpellStore.LookupEntry(53085) ||
- !sSkillLineAbilityStore.LookupEntry(17514) ||
+ if( !sSpellStore.LookupEntry(53085) ||
+ !sSkillLineAbilityStore.LookupEntry(17514) ||
!sMapStore.LookupEntry(598) ||
- !sGemPropertiesStore.LookupEntry(1127) ||
- !sItemExtendedCostStore.LookupEntry(2425) ||
+ !sGemPropertiesStore.LookupEntry(1127) ||
+ !sItemExtendedCostStore.LookupEntry(2425) ||
!sCharTitlesStore.LookupEntry(71) ||
!sAreaStore.LookupEntry(1768) )
{
diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h
index 2c17935d9f5..0375f20c7eb 100644
--- a/src/shared/Database/DBCStores.h
+++ b/src/shared/Database/DBCStores.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DBCSTORES_H
@@ -75,7 +75,6 @@ class DBCStorage
bool Load(char const* fn)
{
-
DBCFile dbc;
// Check if load was sucessful, only then continue
if(!dbc.Load(fn, fmt))
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
index b57b031ef55..a71f80ac8c7 100644
--- a/src/shared/Database/DBCStructure.h
+++ b/src/shared/Database/DBCStructure.h
@@ -10,17 +10,18 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DBCSTRUCTURE_H
#define DBCSTRUCTURE_H
+#include "DBCEnums.h"
#include "Platform/Define.h"
#include <map>
@@ -36,42 +37,6 @@
#pragma pack(push,1)
#endif
-enum AreaTeams
-{
- AREATEAM_NONE = 0,
- AREATEAM_ALLY = 2,
- AREATEAM_HORDE = 4
-};
-
-enum AreaFlags
-{
- AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
- AREA_FLAG_UNK1 = 0x00000002, // unknown, (only Naxxramas and Razorfen Downs)
- AREA_FLAG_UNK2 = 0x00000004, // Only used on development map
- AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // slave capital city flag?
- AREA_FLAG_UNK3 = 0x00000010, // unknown
- AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag?
- AREA_FLAG_UNK4 = 0x00000040, // many zones have this flag
- AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas
- AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag
- AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
- AREA_FLAG_OUTLAND = 0x00000400, // outland zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
- AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
- AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway
- AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 2.4.2)
- AREA_FLAG_OUTLAND2 = 0x00004000, // outland zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
- AREA_FLAG_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
- AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only
- AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 2.4.2)
- AREA_FLAG_UNK5 = 0x00040000, // just used for Amani Pass, Hatchet Hills
- AREA_FLAG_LOWLEVEL = 0x00100000 // used for some starting areas with area_level <=15
-};
-
-enum FactionTemplateFlags
-{
- FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats
-};
-
struct AreaTableEntry
{
uint32 ID; // 0
@@ -179,7 +144,7 @@ struct ChrRacesEntry
//char* string2[16]; // 48-63 used for DBC language detection/selection
// 64 string flags, unused
// 65-67 unused
- uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
+ uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
};
struct CreatureDisplayInfoEntry
@@ -193,12 +158,11 @@ struct CreatureDisplayInfoEntry
struct CreatureFamilyEntry
{
uint32 ID; // 0
- float minScale; // 1
- uint32 minScaleLevel; // 2 0/1
+ float minScale; // 1
+ uint32 minScaleLevel; // 2 0/1
float maxScale; // 3
uint32 maxScaleLevel; // 4 0/60
- uint32 skillLine; // 5
- uint32 skillLine2; // 6
+ uint32 skillLine[2]; // 5-6
uint32 petFoodMask; // 7
char* Name[16]; // 8-23
// 24 string flags, unused
@@ -244,15 +208,6 @@ struct FactionEntry
// 52 string flags, unused
};
-enum FactionMasks
-{
- FACTION_MASK_PLAYER = 1, // any player
- FACTION_MASK_ALLIANCE = 2, // player or creature from alliance team
- FACTION_MASK_HORDE = 4, // player or creature from horde team
- FACTION_MASK_MONSTER = 8 // aggressive creature from monster team
- // if none flags set then non-aggressive creature
-};
-
struct FactionTemplateEntry
{
uint32 ID; // 0
@@ -301,6 +256,7 @@ struct GemPropertiesEntry
};
#define GT_MAX_LEVEL 100
+
struct GtCombatRatingsEntry
{
float ratio;
@@ -431,15 +387,6 @@ struct MailTemplateEntry
//char* content[16]; // 18-33
};
-enum MapTypes
-{
- MAP_COMMON = 0,
- MAP_INSTANCE = 1,
- MAP_RAID = 2,
- MAP_BATTLEGROUND = 3,
- MAP_ARENA = 4
-};
-
struct MapEntry
{
uint32 MapID; // 0
@@ -545,12 +492,6 @@ struct SkillLineEntry
uint32 spellIcon; // 37
};
-enum AbilytyLearnType
-{
- ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1,
- ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2
-};
-
struct SkillLineAbilityEntry
{
uint32 id; // 0, INDEX
@@ -758,17 +699,6 @@ struct SpellDurationEntry
int32 Duration[3];
};
-enum ItemEnchantmentType
-{
- ITEM_ENCHANTMENT_TYPE_NONE = 0,
- ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1,
- ITEM_ENCHANTMENT_TYPE_DAMAGE = 2,
- ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3,
- ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4,
- ITEM_ENCHANTMENT_TYPE_STAT = 5,
- ITEM_ENCHANTMENT_TYPE_TOTEM = 6
-};
-
struct SpellItemEnchantmentEntry
{
uint32 ID; // 0
@@ -826,14 +756,6 @@ struct TalentTabEntry
//char* internalname; // 22
};
-struct TaxiPathEntry
-{
- uint32 ID;
- uint32 from;
- uint32 to;
- uint32 price;
-};
-
struct TaxiNodesEntry
{
uint32 ID; // 0
@@ -847,15 +769,24 @@ struct TaxiNodesEntry
uint32 alliance_mount_type; // 24
};
-enum TotemCategoryType
+struct TaxiPathEntry
+{
+ uint32 ID;
+ uint32 from;
+ uint32 to;
+ uint32 price;
+};
+
+struct TaxiPathNodeEntry
{
- TOTEM_CATEGORY_TYPE_KNIFE = 1,
- TOTEM_CATEGORY_TYPE_TOTEM = 2,
- TOTEM_CATEGORY_TYPE_ROD = 3,
- TOTEM_CATEGORY_TYPE_PICK = 21,
- TOTEM_CATEGORY_TYPE_STONE = 22,
- TOTEM_CATEGORY_TYPE_HAMMER = 23,
- TOTEM_CATEGORY_TYPE_SPANNER = 24
+ uint32 path;
+ uint32 index;
+ uint32 mapid;
+ float x;
+ float y;
+ float z;
+ uint32 actionFlag;
+ uint32 delay;
};
struct TotemCategoryEntry
diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
index b9168cbc416..720e6e3e683 100644
--- a/src/shared/Database/SQLStorage.cpp
+++ b/src/shared/Database/SQLStorage.cpp
@@ -10,18 +10,16 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "SQLStorage.h"
-#include "ProgressBar.h"
-#include "Log.h"
-#include "dbcfile.h"
+#include "SQLStorageImpl.h"
#ifdef DO_POSTGRESQL
extern DatabasePostgre WorldDatabase;
@@ -29,165 +27,57 @@ extern DatabasePostgre WorldDatabase;
extern DatabaseMysql WorldDatabase;
#endif
-const char CreatureInfofmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiis";
+const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiis";
+const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiii";
const char CreatureDataAddonInfofmt[]="iiiiiiis";
const char CreatureModelfmt[]="iffbi";
const char CreatureInfoAddonInfofmt[]="iiiiiiis";
const char EquipmentInfofmt[]="iiiiiiiiii";
-const char GameObjectInfofmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";
-const char ItemPrototypefmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii";
+const char GameObjectInfosrcfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";
+const char GameObjectInfodstfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiii";
+const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii";
+const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiii";
const char PageTextfmt[]="isi";
const char SpellThreatfmt[]="ii";
-const char InstanceTemplatefmt[]="iiiiiiffffs";
+const char InstanceTemplatesrcfmt[]="iiiiiiffffs";
+const char InstanceTemplatedstfmt[]="iiiiiiffffi";
-SQLStorage sCreatureStorage(CreatureInfofmt,"entry","creature_template");
+SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template");
SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
SQLStorage sCreatureModelStorage(CreatureModelfmt,"modelid","creature_model_info");
SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_template_addon");
SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template");
-SQLStorage sGOStorage(GameObjectInfofmt,"entry","gameobject_template");
-SQLStorage sItemStorage(ItemPrototypefmt,"entry","item_template");
+SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameobject_template");
+SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template");
SQLStorage sPageTextStore(PageTextfmt,"entry","page_text");
SQLStorage sSpellThreatStore(SpellThreatfmt,"entry","spell_threat");
-SQLStorage sInstanceTemplate(InstanceTemplatefmt,"map","instance_template");
+SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template");
void SQLStorage::Free ()
{
uint32 offset=0;
for(uint32 x=0;x<iNumFields;x++)
- if (format[x]==FT_STRING)
+ if (dst_format[x]==FT_STRING)
{
for(uint32 y=0;y<MaxEntry;y++)
if(pIndex[y])
delete [] *(char**)((char*)(pIndex[y])+offset);
- offset+=sizeof(char*);
+ offset += sizeof(char*);
}
- else if (format[x]==FT_LOGIC)
- offset+=sizeof(bool);
- else if (format[x]==FT_BYTE)
- offset+=sizeof(char);
+ else if (dst_format[x]==FT_LOGIC)
+ offset += sizeof(bool);
+ else if (dst_format[x]==FT_BYTE)
+ offset += sizeof(char);
else
- offset+=4;
+ offset += 4;
delete [] pIndex;
delete [] data;
}
-void SQLStorage::Load ()
+void SQLStorage::Load()
{
- uint32 maxi;
- Field *fields;
- QueryResult *result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s",entry_field,table);
- if(!result)
- {
- sLog.outError("Error loading %s table (not exist?)\n",table);
- exit(1); // Stop server at loading non exited table or not accessable table
- }
-
- maxi= (*result)[0].GetUInt32()+1;
- delete result;
-
- result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s",table);
- if(result)
- {
- fields = result->Fetch();
- RecordCount=fields[0].GetUInt32();
- delete result;
- }
- else
- RecordCount = 0;
-
- result = WorldDatabase.PQuery("SELECT * FROM %s",table);
-
- if(!result)
- {
- sLog.outError("%s table is empty!\n",table);
- RecordCount = 0;
- return;
- }
-
- uint32 recordsize=0;
- uint32 offset=0;
-
- if(iNumFields!=result->GetFieldCount())
- {
- RecordCount = 0;
- sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n",table,iNumFields);
- delete result;
- exit(1); // Stop server at loading broken or non-compatiable table.
- }
-
- //get struct size
- uint32 sc=0;
- uint32 bo=0;
- uint32 bb=0;
- for(uint32 x=0;x<iNumFields;x++)
- if(format[x]==FT_STRING)
- ++sc;
- else if (format[x]==FT_LOGIC)
- ++bo;
- else if (format[x]==FT_BYTE)
- ++bb;
- recordsize=(iNumFields-sc-bo-bb)*4+sc*sizeof(char*)+bo*sizeof(bool)+bb*sizeof(char);
-
- char** newIndex=new char*[maxi];
- memset(newIndex,0,maxi*sizeof(char*));
-
- char * _data= new char[RecordCount *recordsize];
- uint32 count=0;
- barGoLink bar( RecordCount );
- do
- {
- fields = result->Fetch();
- bar.step();
- char *p=(char*)&_data[recordsize*count];
- newIndex[fields[0].GetUInt32()]=p;
-
- offset=0;
- for(uint32 x=0;x<iNumFields;x++)
- switch(format[x])
- {
- case FT_LOGIC:
- *((bool*)(&p[offset]))=(fields[x].GetUInt32()>0);
- offset+=sizeof(bool);
- break;
- case FT_BYTE:
- *((char*)(&p[offset]))=(fields[x].GetUInt8());
- offset+=sizeof(char);
- break;
- case FT_INT:
- *((uint32*)(&p[offset]))=fields[x].GetUInt32();
- offset+=sizeof(uint32);
- break;
- case FT_FLOAT:
- *((float*)(&p[offset]))=fields[x].GetFloat();
- offset+=sizeof(float);
- break;
- case FT_STRING:
- char const* tmp = fields[x].GetString();
- char* st;
- if(!tmp)
- {
- st=new char[1];
- *st=0;
- }
- else
- {
- uint32 l=strlen(tmp)+1;
- st=new char[l];
- memcpy(st,tmp,l);
- }
- *((char**)(&p[offset]))=st;
- offset+=sizeof(char*);
- break;
- }
- ++count;
- }while( result->NextRow() );
-
- delete result;
-
- pIndex =newIndex;
- MaxEntry=maxi;
- data=_data;
+ SQLStorageLoader loader;
+ loader.Load(*this);
}
diff --git a/src/shared/Database/SQLStorage.h b/src/shared/Database/SQLStorage.h
index 5131a73fe4d..2d154f4e1ca 100644
--- a/src/shared/Database/SQLStorage.h
+++ b/src/shared/Database/SQLStorage.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SQLSTORAGE_H
@@ -26,18 +26,26 @@
class SQLStorage
{
+ template<class T>
+ friend struct SQLStorageLoaderBase;
+
public:
- SQLStorage(const char*fmt,const char * _entry_field,const char * sqlname)
+ SQLStorage(const char* fmt, const char * _entry_field, const char * sqlname)
{
- format=fmt;
- entry_field = _entry_field;
- table=sqlname;
- data=NULL;
- pIndex=NULL;
- iNumFields =strlen(fmt);
- MaxEntry = 0;
+ src_format = fmt;
+ dst_format = fmt;
+ init(_entry_field, sqlname);
+ }
+
+ SQLStorage(const char* src_fmt, const char* dst_fmt, const char * _entry_field, const char * sqlname)
+ {
+ src_format = src_fmt;
+ dst_format = dst_fmt;
+ init(_entry_field, sqlname);
}
+
+
~SQLStorage()
{
Free();
@@ -56,15 +64,53 @@ class SQLStorage
uint32 RecordCount;
uint32 MaxEntry;
uint32 iNumFields;
+
void Load();
void Free();
+
private:
+ void init(const char * _entry_field, const char * sqlname)
+ {
+ entry_field = _entry_field;
+ table=sqlname;
+ data=NULL;
+ pIndex=NULL;
+ iNumFields = strlen(src_format);
+ MaxEntry = 0;
+ }
+
char** pIndex;
char *data;
- const char *format;
+ const char *src_format;
+ const char *dst_format;
const char *table;
const char *entry_field;
//bool HasString;
};
+
+template <class T>
+struct SQLStorageLoaderBase
+{
+ public:
+ void Load(SQLStorage &storage);
+
+ template<class S, class D>
+ void convert(uint32 field_pos, S src, D &dst);
+ template<class S>
+ void convert_to_str(uint32 field_pos, S src, char * & dst);
+ template<class D>
+ void convert_from_str(uint32 field_pos, char * src, D& dst);
+ void convert_str_to_str(uint32 field_pos, char *src, char *&dst);
+
+ private:
+ template<class V>
+ void storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset);
+ void storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset);
+};
+
+struct SQLStorageLoader : public SQLStorageLoaderBase<SQLStorageLoader>
+{
+};
+
#endif
diff --git a/src/shared/Database/SQLStorageImpl.h b/src/shared/Database/SQLStorageImpl.h
new file mode 100644
index 00000000000..2ccd5724a07
--- /dev/null
+++ b/src/shared/Database/SQLStorageImpl.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ProgressBar.h"
+#include "Log.h"
+#include "dbcfile.h"
+
+template<class T>
+template<class S, class D>
+void SQLStorageLoaderBase<T>::convert(uint32 field_pos, S src, D &dst)
+{
+ dst = D(src);
+}
+
+template<class T>
+void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 field_pos, char *src, char *&dst)
+{
+ if(!src)
+ {
+ dst = new char[1];
+ *dst = 0;
+ }
+ else
+ {
+ uint32 l = strlen(src) + 1;
+ dst = new char[l];
+ memcpy(dst, src, l);
+ }
+}
+
+template<class T>
+template<class S>
+void SQLStorageLoaderBase<T>::convert_to_str(uint32 field_pos, S src, char * & dst)
+{
+ dst = new char[1];
+ *dst = 0;
+}
+
+template<class T>
+template<class D>
+void SQLStorageLoaderBase<T>::convert_from_str(uint32 field_pos, char * src, D& dst)
+{
+ dst = 0;
+}
+
+template<class T>
+template<class V>
+void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset)
+{
+ T * subclass = (static_cast<T*>(this));
+ switch(store.dst_format[x])
+ {
+ case FT_LOGIC:
+ subclass->convert(x, value, *((bool*)(&p[offset])) );
+ offset+=sizeof(bool);
+ break;
+ case FT_BYTE:
+ subclass->convert(x, value, *((char*)(&p[offset])) );
+ offset+=sizeof(char);
+ break;
+ case FT_INT:
+ subclass->convert(x, value, *((uint32*)(&p[offset])) );
+ offset+=sizeof(uint32);
+ break;
+ case FT_FLOAT:
+ subclass->convert(x, value, *((float*)(&p[offset])) );
+ offset+=sizeof(float);
+ break;
+ case FT_STRING:
+ subclass->convert_to_str(x, value, *((char**)(&p[offset])) );
+ offset+=sizeof(char*);
+ break;
+ }
+}
+
+template<class T>
+void SQLStorageLoaderBase<T>::storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset)
+{
+ T * subclass = (static_cast<T*>(this));
+ switch(store.dst_format[x])
+ {
+ case FT_LOGIC:
+ subclass->convert_from_str(x, value, *((bool*)(&p[offset])) );
+ offset+=sizeof(bool);
+ break;
+ case FT_BYTE:
+ subclass->convert_from_str(x, value, *((char*)(&p[offset])) );
+ offset+=sizeof(char);
+ break;
+ case FT_INT:
+ subclass->convert_from_str(x, value, *((uint32*)(&p[offset])) );
+ offset+=sizeof(uint32);
+ break;
+ case FT_FLOAT:
+ subclass->convert_from_str(x, value, *((float*)(&p[offset])) );
+ offset+=sizeof(float);
+ break;
+ case FT_STRING:
+ subclass->convert_str_to_str(x, value, *((char**)(&p[offset])) );
+ offset+=sizeof(char*);
+ break;
+ }
+}
+
+template<class T>
+void SQLStorageLoaderBase<T>::Load(SQLStorage &store)
+{
+ uint32 maxi;
+ Field *fields;
+ QueryResult *result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.entry_field, store.table);
+ if(!result)
+ {
+ sLog.outError("Error loading %s table (not exist?)\n", store.table);
+ exit(1); // Stop server at loading non exited table or not accessable table
+ }
+
+ maxi = (*result)[0].GetUInt32()+1;
+ delete result;
+
+ result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table);
+ if(result)
+ {
+ fields = result->Fetch();
+ store.RecordCount = fields[0].GetUInt32();
+ delete result;
+ }
+ else
+ store.RecordCount = 0;
+
+ result = WorldDatabase.PQuery("SELECT * FROM %s", store.table);
+
+ if(!result)
+ {
+ sLog.outError("%s table is empty!\n", store.table);
+ store.RecordCount = 0;
+ return;
+ }
+
+ uint32 recordsize = 0;
+ uint32 offset = 0;
+
+ if(store.iNumFields != result->GetFieldCount())
+ {
+ store.RecordCount = 0;
+ sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n", store.table, store.iNumFields);
+ delete result;
+ exit(1); // Stop server at loading broken or non-compatible table.
+ }
+
+ //get struct size
+ uint32 sc=0;
+ uint32 bo=0;
+ uint32 bb=0;
+ for(uint32 x=0; x< store.iNumFields; x++)
+ if(store.dst_format[x]==FT_STRING)
+ ++sc;
+ else if (store.dst_format[x]==FT_LOGIC)
+ ++bo;
+ else if (store.dst_format[x]==FT_BYTE)
+ ++bb;
+ recordsize=(store.iNumFields-sc-bo-bb)*4+sc*sizeof(char*)+bo*sizeof(bool)+bb*sizeof(char);
+
+ char** newIndex=new char*[maxi];
+ memset(newIndex,0,maxi*sizeof(char*));
+
+ char * _data= new char[store.RecordCount *recordsize];
+ uint32 count=0;
+ barGoLink bar( store.RecordCount );
+ do
+ {
+ fields = result->Fetch();
+ bar.step();
+ char *p=(char*)&_data[recordsize*count];
+ newIndex[fields[0].GetUInt32()]=p;
+
+ offset=0;
+ for(uint32 x = 0; x < store.iNumFields; x++)
+ switch(store.src_format[x])
+ {
+ case FT_LOGIC:
+ storeValue((bool)(fields[x].GetUInt32() > 0), store, p, x, offset); break;
+ case FT_BYTE:
+ storeValue((char)fields[x].GetUInt8(), store, p, x, offset); break;
+ case FT_INT:
+ storeValue((uint32)fields[x].GetUInt32(), store, p, x, offset); break;
+ case FT_FLOAT:
+ storeValue((float)fields[x].GetFloat(), store, p, x, offset); break;
+ case FT_STRING:
+ storeValue((char*)fields[x].GetString(), store, p, x, offset); break;
+ }
+ ++count;
+ }while( result->NextRow() );
+
+ delete result;
+
+ store.pIndex = newIndex;
+ store.MaxEntry = maxi;
+ store.data = _data;
+}
diff --git a/src/shared/Database/dbcfile.cpp b/src/shared/Database/dbcfile.cpp
index 07f7b662e73..c6c12a99b8b 100644
--- a/src/shared/Database/dbcfile.cpp
+++ b/src/shared/Database/dbcfile.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
diff --git a/src/shared/Database/dbcfile.h b/src/shared/Database/dbcfile.h
index cc2f117d6d1..8d0b2e45451 100644
--- a/src/shared/Database/dbcfile.h
+++ b/src/shared/Database/dbcfile.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DBCFILE_H
diff --git a/src/shared/ProgressBar.cpp b/src/shared/ProgressBar.cpp
index 724e749c1d9..f4163a6133e 100644
--- a/src/shared/ProgressBar.cpp
+++ b/src/shared/ProgressBar.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ProgressBar.h"
diff --git a/src/shared/ProgressBar.h b/src/shared/ProgressBar.h
index de73596dd55..98720c90385 100644
--- a/src/shared/ProgressBar.h
+++ b/src/shared/ProgressBar.h
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_PROGRESSBAR_H
#define TRINITYCORE_PROGRESSBAR_H
diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp
index 065a6662a50..0af892819b6 100644
--- a/src/trinitycore/CliRunnable.cpp
+++ b/src/trinitycore/CliRunnable.cpp
@@ -169,7 +169,7 @@ bool ChatHandler::HandleCharacterDeleteCommand(const char* args)
bool ChatHandler::HandleServerExitCommand(const char* args)
{
SendSysMessage(LANG_COMMAND_EXIT);
- World::m_stopEvent = true;
+ World::StopNow(SHUTDOWN_EXIT_CODE);
return true;
}
@@ -310,14 +310,14 @@ void CliRunnable::run()
printf("TC>");
///- As long as the World is running (no World::m_stopEvent), get the command line and handle it
- while (!World::m_stopEvent)
+ while (!World::IsStopped())
{
fflush(stdout);
#ifdef linux
- while (!kb_hit_return() && !World::m_stopEvent)
+ while (!kb_hit_return() && !World::IsStopped())
// With this, we limit CLI to 10commands/second
usleep(100);
- if (World::m_stopEvent)
+ if (World::IsStopped())
break;
#endif
char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin);
@@ -348,7 +348,7 @@ void CliRunnable::run()
}
else if (feof(stdin))
{
- World::m_stopEvent = true;
+ World::StopNow(SHUTDOWN_EXIT_CODE);
}
}
diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp
index 47a12484151..317a3a31a15 100644
--- a/src/trinitycore/Master.cpp
+++ b/src/trinitycore/Master.cpp
@@ -77,7 +77,7 @@ public:
w_loops = 0;
m_lastchange = 0;
w_lastchange = 0;
- while(!World::m_stopEvent)
+ while(!World::IsStopped())
{
ZThread::Thread::sleep(1000);
uint32 curtime = getMSTime();
@@ -172,13 +172,13 @@ public:
// if use ra spend time waiting for io, if not use ra ,just sleep
if (usera)
- while (!World::m_stopEvent)
+ while (!World::IsStopped())
{
h.Select (0, socketSelecttime);
checkping ();
}
else
- while (!World::m_stopEvent)
+ while (!World::IsStopped())
{
ZThread::Thread::sleep (static_cast<unsigned long> (socketSelecttime / 1000));
checkping ();
@@ -323,7 +323,7 @@ int Master::Run()
if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1)
{
sLog.outError ("Failed to start network");
- World::m_stopEvent = true;
+ World::StopNow(ERROR_EXIT_CODE);
// go down and shutdown the server
}
@@ -394,7 +394,8 @@ int Master::Run()
// fixes a memory leak related to detaching threads from the module
UnloadScriptingModule();
- return sWorld.GetShutdownMask() & SHUTDOWN_MASK_RESTART ? 2 : 0;
+ // Exit the process with specified return value
+ return World::GetExitCode();
}
/// Initialize connection to the databases
@@ -477,17 +478,18 @@ void Master::clearOnlineAccounts()
}
/// Handle termination signals
-/** Put the World::m_stopEvent to 'true' if a termination signal is caught **/
void Master::_OnSignal(int s)
{
switch (s)
{
case SIGINT:
+ World::StopNow(RESTART_EXIT_CODE);
+ break;
case SIGTERM:
#ifdef _WIN32
case SIGBREAK:
#endif
- World::m_stopEvent = true;
+ World::StopNow(SHUTDOWN_EXIT_CODE);
break;
}
diff --git a/src/trinitycore/WorldRunnable.cpp b/src/trinitycore/WorldRunnable.cpp
index 1a30740ddd9..5592b1d2064 100644
--- a/src/trinitycore/WorldRunnable.cpp
+++ b/src/trinitycore/WorldRunnable.cpp
@@ -51,7 +51,7 @@ void WorldRunnable::run()
uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
///- While we have not World::m_stopEvent, update the world
- while (!World::m_stopEvent)
+ while (!World::IsStopped())
{
++World::m_worldLoopCounter;
realCurrTime = getMSTime();